The client says connection refused right after you regenerated the CRL, so the CRL looks guilty. It is not. Refusal is a transport-layer answer, and certificate validation happens later, inside the tunnel handshake. The timing is context, not proof.

Two checks separate the cases in under a minute, and neither of them involves touching trust settings.

Read the error at the layer that produced it

ECONNREFUSED from connect means the transport attempt was rejected: something answered with a reset, or the stack reported an unreachable port. A certificate problem cannot produce that error, because the TLS handshake never starts without a transport connection. If you see a refusal, the client never got far enough to present a certificate. That single fact rules out revocation as the cause.

The opposite also holds. A revoked certificate produces a completed TCP connection and a failed handshake, logged on the server as a verification error.

TCP refusal: nobody is listening

For TCP, check whether the intended instance is running and bound to the address and port in the profile. ss -lntp shows listeners, and the absence of one is the usual explanation. A firewall that rejects rather than drops produces the same client-side message, which is why you check both.

Check the address family too. A service bound to 127.0.0.1 or to IPv6 only will refuse a client that resolves to the other one.

Then read the service log instead of guessing. A restart after CA maintenance can fail on an unreadable or missing file and never reach the listening state, and the log names the file. That is a startup failure, a different bug from a rejected certificate.

UDP has no handshake to refuse

OpenVPN over UDP does not establish a connection in the TCP sense, so there is nothing to refuse at connect time. On Linux, an error surfaced by a UDP socket can come from an ICMP port-unreachable generated by an earlier datagram. The udp(7) man page describes that asynchronous behaviour.

This is why a UDP client can print a refusal while the server process is running but not bound to the expected address.

Where a CRL actually gets checked

The CRL is consulted during the TLS handshake, after the peer presents its certificate, and only if the server configuration enables it. OpenVPN's crl-verify option points at the file, and a failure appears in the server log as a verification error naming the certificate.

A revoked client therefore connects at the transport layer and then fails authentication. Same server, same port, completely different message.

Check the CRL issuer and validity dates when you do reach that stage. A CRL signed by the wrong CA, or one that expired before the client connected, produces verification failures that have nothing to do with the client's own certificate.

A short runbook for the next occurrence

Confirm the transport first: listener present, correct address family, firewall not rejecting. Then confirm the service reached its listening state by reading the startup log. Then, and only then, look at handshake errors for verification messages. Keep that order fixed, because each step eliminates a whole class of cause.

Write down the transport, the resolved destination, the port and the exact error text. A client reinstall destroys that evidence and usually changes nothing.

Ngaahi tokoni fekau'aki