hashicorp/nomad · error
missing certificate information
Error message
missing certificate information
What it means
verifyTLS enforces mutual TLS on RPC connections: when verification is required and the connection is not static, ctx.Certificate() must return the peer's TLS certificate. If it is nil, the connection somehow arrived without a client certificate, so authentication cannot proceed and this error is thrown.
Source
Thrown at nomad/auth/auth.go:410
identity.ClientID = claims.NodeIdentityClaims.NodeID
identity.Claims = claims
}
return s.ResolveClientIdentityACL(identity)
}
// verifyTLS is a helper function that performs TLS verification, if required,
// given the passed RPCContext and valid names.
//
// It will always set the TLSName on the identity if we are performing
// verification, so callers don't have to worry about setting it themselves.
func verifyTLS(verify bool, ctx RPCContext, validNames []string, identity *structs.AuthenticatedIdentity) error {
if verify && !ctx.IsStatic() {
tlsCert := ctx.Certificate()
if tlsCert == nil {
return errors.New("missing certificate information")
}
// Always set on the identity, even before validating the name, so we
// can capture it for metrics.
identity.TLSName = tlsCert.Subject.CommonName
// Perform the certificate validation, using the passed valid names.
_, err := validateCertificateForNames(tlsCert, validNames)
if err != nil {
return err
}
}
return nil
}
// validateCertificateForNames returns true if the certificate is valid for any
// of the given domain names.View on GitHub (pinned to 482b49bf1a)
Solutions
- Configure the connecting agent/client with both ca_file, cert_file, and key_file so it presents a client certificate during the TLS handshake.
- Verify verify_incoming/verify_outgoing TLS settings in server and client configs are consistent (both sides expecting mTLS).
- If TLS is terminated at a proxy, use the proxy's client-cert passthrough or forward the identity in a way Nomad's RPC surface accepts.
- Confirm the connection is actually using TLS (check rpc port config and tls setting) rather than plaintext hitting a verified path.
Example fix
// before: client HCL with no client cert
tls { http = true, rpc = true, ca_file = "ca.pem" }
// after: present a client certificate
tls { http = true, rpc = true, ca_file = "ca.pem", cert_file = "client.pem", key_file = "client-key.pem" } Defensive patterns
Strategy: validation
Validate before calling
// confirm the client is configured for mTLS before dialing
if tlsConfig.Certificates == nil || len(tlsConfig.Certificates) == 0 {
return errors.New("client TLS config must include cert_file/key_file for mTLS")
} Type guard
func hasClientCert(conn *tls.Conn) bool {
state := conn.ConnectionState()
return len(state.PeerCertificates) > 0
} Prevention
- Always set cert_file and key_file on clients in mTLS-enabled clusters.
- Never terminate TLS at a proxy without cert passthrough when verify_incoming is on.
- Test with `openssl s_client -cert ...` that the client cert is presented and accepted.
When it happens
Trigger: Calling AuthenticateServerOnly, AuthenticateNodeIdentityGenerator, or AuthenticateClientOnly with verify=true against an RPCContext whose TLS handshake did not yield a client certificate — e.g. a plaintext connection routed into a TLS-verified path, or a client connecting without presenting a cert.
Common situations: Client configured with TLS but no cert/key (verify_incoming setups missing client certs); proxy/load balancer terminating TLS so Nomad never sees the peer cert; mixed TLS/plaintext RPC ports misconfigured; static/loopback connections bypassing the check while real agent connections lack certs.
Understand the failure class
- SSL/TLS and certificate errors — how TLS handshakes and certificate validation fail.
Related errors
- VerifyIncoming set, and no CA certificate provided!
- VerifyIncoming set, and no Cert/Key pair provided!
- could not resolve node secret: %w
- could not resolve user: %w
- invalid certificate: %s not in expected %s
AI-assisted analysis of hashicorp/nomad@482b49bf1a (2026-09-04).
Data as JSON: /api/errors/3d5a98b9de2e43cb.
Report an issue: GitHub.