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

  1. Configure the connecting agent/client with both ca_file, cert_file, and key_file so it presents a client certificate during the TLS handshake.
  2. Verify verify_incoming/verify_outgoing TLS settings in server and client configs are consistent (both sides expecting mTLS).
  3. 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.
  4. 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

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

Related errors


AI-assisted analysis of hashicorp/nomad@482b49bf1a (2026-09-04). Data as JSON: /api/errors/3d5a98b9de2e43cb. Report an issue: GitHub.