dgraph-io/dgraph · critical

%s: verification failed

Error message

%s: verification failed

What it means

verifyCert (dgraph/cmd/cert/cert.go:171) wraps the error returned by x509.Certificate.Verify when the freshly created node or client cert fails chain verification against its parent CA (Roots pool built from c.parent). The wrapped err from the stdlib explains the actual cause: expired, unknown authority, wrong key usage, hostname mismatch, etc. It is returned right after cert creation, so it means the new cert is not usable.

Source

Thrown at dgraph/cmd/cert/cert.go:171

	roots.AddCert(c.parent)
	opts := x509.VerifyOptions{Roots: roots}

	if c.hosts != nil {
		opts.KeyUsages = []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth,
			x509.ExtKeyUsageClientAuth}
		for i := range c.hosts {
			if err := cert.VerifyHostname(c.hosts[i]); err != nil {
				return err
			}
		}
	}
	if c.client != "" {
		opts.KeyUsages = []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth}
	}

	_, err = cert.Verify(opts)
	if err != nil {
		return errors.Wrapf(err, "%s: verification failed", certFile)
	}

	return nil
}

View on GitHub (pinned to 759e242be6)

Solutions

  1. Read the wrapped x509 error to identify the cause (UnknownAuthority, Expired, IncompatibleKeyUsage).
  2. Regenerate the full chain together: `dgraph cert --ca --force` then `dgraph cert --node --client --force` so parent and leaves match.
  3. Verify the files are a matching pair with `dgraph cert --info` or `openssl verify -CAfile ca.crt node.crt`.
  4. Check clock/NotBefore skew if the error is 'certificate is not valid yet'.

Example fix

# before: mixing an old CA with new node certs
dgraph cert --node --force
# after: regenerate CA and leaves together
dgraph cert --ca --node --client --force
Defensive patterns

Strategy: try-catch

Validate before calling

// Pre-verify chain outside the tool before trusting the generated cert
roots := x509.NewCertPool()
ca, _ := readCert("ca.crt")
roots.AddCert(ca)
cert, err := readCert("node.crt")
if err == nil {
    if _, err := cert.Verify(x509.VerifyOptions{Roots: roots}); err != nil {
        fmt.Println("chain invalid:", err)
    }
}

Try / catch

if err := verifyCert("node.crt"); err != nil {
    var inner error
    if unwrapped, ok := err.(*errors.Error); ok && errors.Is(err, x509.CertificateInvalidError{}) {
        inner = unwrapped.Unwrap()
    }
    // inspect inner: UnknownAuthority/Expired/IncompatibleKeyUsage
    return fmt.Errorf("regenerate chain: %w", err)
}

Prevention

When it happens

Trigger: createNodePair or createClientPair generates a cert and then calls verifyCert; cert.Verify fails because the CA expired, the CA cert is not the actual signer, the cert's KeyUsages don't match the requested ExtKeyUsage (ServerAuth/ClientAuth), or the chain is otherwise untrusted (e.g. mismatched ca.crt/key or corrupted files).

Common situations: ca.crt was regenerated after the node/client cert, so the signer no longer matches; mixing files from different --force regenerations; system clock skew making certs not-yet-valid or expired; manually edited/re-issued certs with mismatched key usage.

Related errors


AI-assisted analysis of dgraph-io/dgraph@759e242be6 (2026-09-01). Data as JSON: /api/errors/1da0425ce8c78cd4. Report an issue: GitHub.