{"record":{"id":"ab84ad6fc7d764d9","repo":"caddyserver/caddy","slug":"failed-to-provision-default-ca-s","errorCode":null,"errorMessage":"failed to provision default CA: %s","messagePattern":"failed to provision default CA: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"modules/caddypki/pki.go","lineNumber":139,"sourceCode":"func (p *PKI) Stop() error {\n\treturn nil\n}\n\n// GetCA retrieves a CA by ID. If the ID is the default\n// CA ID, and it hasn't been provisioned yet, it will\n// be provisioned.\nfunc (p *PKI) GetCA(ctx caddy.Context, id string) (*CA, error) {\n\tca, ok := p.CAs[id]\n\tif !ok {\n\t\t// for anything other than the default CA ID, error out if it wasn't configured\n\t\tif id != DefaultCAID {\n\t\t\treturn nil, fmt.Errorf(\"no certificate authority configured with id: %s\", id)\n\t\t}\n\n\t\t// for the default CA ID, provision it, because we want it to \"just work\"\n\t\terr := p.ProvisionDefaultCA(ctx)\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"failed to provision default CA: %s\", err)\n\t\t}\n\t\tca = p.CAs[id]\n\t}\n\n\treturn ca, nil\n}\n\n// Interface guards\nvar (\n\t_ caddy.Provisioner = (*PKI)(nil)\n\t_ caddy.App         = (*PKI)(nil)\n)\n","sourceCodeStart":121,"sourceCodeEnd":152,"githubUrl":"https://github.com/caddyserver/caddy/blob/50e54ee279aa1e504fe218ca49ab6ae16c100410/modules/caddypki/pki.go#L121-L152","documentation":"Returned by PKI.GetCA (modules/caddypki/pki.go:139) when the default CA id was requested but not yet provisioned, and the lazy call to ProvisionDefaultCA fails. It wraps the provisioning error, which typically points at storage or filesystem problems rather than user config, since the default CA requires no configuration.","triggerScenarios":"A module (e.g. the internal TLS issuer) calls GetCA(ctx, 'local') before any CA exists and ProvisionDefaultCA fails - unwritable storage for <storage>/pki/authorities/local, a failing custom storage backend, or permission errors creating the root/intermediate key files.","commonSituations":"Same as other default-CA provisioning failures: container users without write access to the data volume, read-only filesystems, network storage plugins that cannot create directories, or disk quota exhaustion during first-run key generation.","solutions":["Read the wrapped error and fix the underlying storage/permission issue (chown the storage dir to the service user; ensure the volume is writable)","Validate with caddy validate --config <file> run as the same user as the daemon","If a custom storage module is in play, test it standalone or temporarily switch to file-system storage to confirm","After fixing, restart Caddy so GetCA re-attempts provisioning"],"exampleFix":"# before\nvolumes:\n  - ./caddy-data:/data   # owned by root, caddy runs as app\n\n# after\nvolumes:\n  - ./caddy-data:/data\n# ensure ownership\n#   chown -R 1000:1000 ./caddy-data","handlingStrategy":"validation","validationCode":"# before starting, verify the default CA can write its storage\nsudo -u caddy mkdir -p /var/lib/caddy/pki/authorities/local\nsudo -u caddy touch /var/lib/caddy/pki/authorities/local/.probe && rm /var/lib/caddy/pki/authorities/local/.probe","typeGuard":null,"tryCatchPattern":"ca, err := p.GetCA(ctx, DefaultCAID)\nif err != nil {\n    // wrapped message names the real cause (storage/permissions);\n    // fix environment, then restart so GetCA lazily re-provisions\n    return nil, err\n}","preventionTips":["Ensure the storage directory is writable by the service user before first start","Containerize with a named volume for /data so the default CA survives and stays writable","Monitor first-start logs; a failed default-CA provisioning usually repeats on every request needing TLS"],"tags":["pki","default-ca","storage","lazy-provisioning"],"backgroundTag":null,"analyzedSha":"50e54ee279aa1e504fe218ca49ab6ae16c100410","analyzedAt":"2026-08-15T09:20:21.641Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}