hashicorp/nomad · error

could not read -jwks-certfile: %v

Error message

could not read -jwks-certfile: %v

What it means

renderAuthMethod optionally embeds a CA certificate for verifying the Nomad JWKS endpoint into the Consul auth method config. When -jwks-certfile (jwksCACertPath) is set, the file is read with os.ReadFile; any read failure (missing file, permissions, path errors) produces this wrapped error.

Source

Thrown at command/setup_consul.go:440

		existingMethods,
		func(m *api.ACLAuthMethodListEntry) bool { return m.Name == authMethodName })
}

func (s *SetupConsulCommand) renderAuthMethod(name string, desc string) (*api.ACLAuthMethod, error) {
	authConfig := map[string]any{}
	err := json.Unmarshal(consulAuthConfigBody, &authConfig)
	if err != nil {
		return nil, fmt.Errorf("default auth config text could not be deserialized: %v", err)
	}

	authConfig["JWKSURL"] = s.jwksURL
	authConfig["BoundAudiences"] = []string{consulAud}
	authConfig["JWTSupportedAlgs"] = []string{"RS256"}

	if s.jwksCACertPath != "" {
		caCert, err := os.ReadFile(s.jwksCACertPath)
		if err != nil {
			return nil, fmt.Errorf("could not read -jwks-certfile: %v", err)
		}
		authConfig["JWKSCACert"] = string(caCert)
	}

	method := &api.ACLAuthMethod{
		Name:          name,
		Type:          "jwt",
		DisplayName:   name,
		Description:   desc,
		TokenLocality: "local",
		Config:        authConfig,
	}
	if s.consulEnt {
		method.NamespaceRules = []*api.ACLAuthMethodNamespaceRule{{
			Selector:      `"consul_namespace" in value`,
			BindNamespace: "${value.consul_namespace}",
		}}
	}

View on GitHub (pinned to 482b49bf1a)

Solutions

  1. Verify the file exists at the given path (`ls -l <path>`) and use an absolute path in -jwks-certfile.
  2. Fix permissions so the user running nomad setup can read the file (`chmod 644 /path/ca.pem`).
  3. If the CA cert is unnecessary (TLS not used / JWKS served over HTTP), omit -jwks-certfile entirely.
  4. Re-copy the CA certificate from the Nomad server if the file was removed (it is the same CA Nomad's TLS config uses).

Example fix

# before
nomad setup consul -jwks-certfile ./ca.pem
// after
nomad setup consul -jwks-certfile /etc/nomad.d/tls/ca.pem  # absolute, existing path
Defensive patterns

Strategy: validation

Validate before calling

if s.jwksCACertPath != "" {
    if info, err := os.Stat(s.jwksCACertPath); err != nil {
        return fmt.Errorf("-jwks-certfile %q not accessible: %v", s.jwksCACertPath, err)
    } else if info.IsDir() {
        return fmt.Errorf("-jwks-certfile %q is a directory", s.jwksCACertPath)
    }
}

Try / catch

caCert, err := os.ReadFile(s.jwksCACertPath)
if err != nil {
    if os.IsNotExist(err) {
        return fmt.Errorf("-jwks-certfile %q does not exist; check the path", s.jwksCACertPath)
    }
    return fmt.Errorf("could not read -jwks-certfile: %v", err)
}

Prevention

When it happens

Trigger: `nomad setup consul -jwks-certfile /path/to/ca.pem` where the file does not exist, the path is wrong relative to the working directory, the process lacks read permission, or the argument points to a directory.

Common situations: Typo in the cert path; running the setup command from a different directory than expected with a relative path; the CA file was moved or deleted after generating it for Nomad's TLS config; permission issues when running nomad setup under a service account or container without the cert mounted.

Understand the failure class

Background: "File not found" and ENOENT errors: why libraries can't find a file that should exist — this error's family across 50 libraries.

Related errors


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