k3s-io/k3s · error
no certificates loaded from etcd-s3-endpoint-ca
Error message
no certificates loaded from etcd-s3-endpoint-ca
What it means
The S3 TLS setup builds a cert pool from the etcd-s3-endpoint-ca sources (file on disk and/or data from the config secret) and sets 'loaded' only when AppendCertsFromPEM accepts at least one PEM block. If every source is empty, missing, or not parseable PEM, the pool stays empty and this error is returned.
Source
Thrown at pkg/etcd/s3/s3.go:587
// contains multiline, ascii-armored, base64-encoded certificate data - as would be produced
// by `base64 --wrap=0 /path/to/cert.pem`. If this fails, assume the value is the path to a
// file on disk, and try to read that. This is backwards compatible with RKE1.
caData, err := base64.StdEncoding.DecodeString(ca)
if err != nil {
caData, err = os.ReadFile(ca)
}
if err != nil {
return nil, err
}
if certPool.AppendCertsFromPEM(caData) {
loaded = true
}
}
if loaded {
return &tls.Config{RootCAs: certPool}, nil
}
return nil, errors.New("no certificates loaded from etcd-s3-endpoint-ca")
}
func bucketLookupType(endpoint, lookupType string) minio.BucketLookupType {
switch strings.ToLower(lookupType) {
case "dns":
return minio.BucketLookupDNS
case "path":
return minio.BucketLookupPath
}
if strings.Contains(endpoint, "aliyun") { // backwards compatible with RKE1
return minio.BucketLookupDNS
}
return minio.BucketLookupAuto
}
View on GitHub (pinned to 6ba341e396)
Solutions
- Verify the file is valid PEM: openssl x509 -in ca.pem -noout -text (for bundles, check every block with awk).
- Ensure the value is the CA certificate (PEM, possibly a bundle), not DER and not the leaf server cert alone.
- If the CA comes from the config secret, confirm the secret data key and that it is mounted/decoded correctly (no double base64).
Example fix
# before: DER-encoded or truncated CA --etcd-s3-endpoint-ca=/etc/ssl/ca.der # after: PEM bundle, verified first openssl x509 -in /etc/ssl/ca.pem -noout || exit 1 --etcd-s3-endpoint-ca=/etc/ssl/ca.pem
Defensive patterns
Strategy: validation
Validate before calling
func validPEM(data []byte) bool {
rest := data
found := false
var block *pem.Block
for {
block, rest = pem.Decode(rest)
if block == nil {
return found
}
if block.Type == "CERTIFICATE" {
found = true
}
}
} Prevention
- Validate CA bundles with openssl x509 -noout in CI before mounting them.
- Store bundles as PEM; never DER; watch for truncated multi-cert chains.
When it happens
Trigger: Setting --etcd-s3-endpoint-ca to a path whose file is empty/truncated/not PEM, or an etcd-s3-config secret whose CA field contains base64 garbage or a DER-encoded (binary) certificate instead of PEM.
Common situations: Fetched the cert with openssl s_client without -showcerts and got a partial chain; copied the server cert instead of the CA; trailing junk before the BEGIN CERTIFICATE line; envs where the CA file is mounted empty until an init job runs.
Understand the failure class
- SSL/TLS and certificate errors — how TLS handshakes and certificate validation fail.
Related errors
- service %s is not recognized
- etcd-s3-timeout must be greater than 0s
- s3 configuration was not set
- s3 bucket name was not set
- proxy URL must include scheme and host
AI-assisted analysis of k3s-io/k3s@6ba341e396 (2026-08-15).
Data as JSON: /api/errors/d92b2b56368a21c8.
Report an issue: GitHub.