istio/istio · error
secret %v/%v not found
Error message
secret %v/%v not found
What it means
Returned by CredentialsController.GetCertInfo when the informer cache lookup s.secrets.Get(name, namespace) returns nil: no Kubernetes Secret with that name exists (or has reached the cache) in the namespace. This is the leaf-certificate lookup used for Gateway credentialName and similar SDS pushes.
Source
Thrown at pilot/pkg/credentials/kube/secrets.go:222
User: user,
},
}, metav1.CreateOptions{})
if err != nil {
return err
}
if !resp.Status.Allowed {
return fmt.Errorf("%s/%s is not authorized to read secrets: %v", serviceAccount, namespace, resp.Status.Reason)
}
return nil
}()
s.insertCache(user, err)
return err
}
func (s *CredentialsController) GetCertInfo(name, namespace string) (certInfo *credentials.CertInfo, err error) {
k8sSecret := s.secrets.Get(name, namespace)
if k8sSecret == nil {
return nil, fmt.Errorf("secret %v/%v not found", namespace, name)
}
return ExtractCertInfo(k8sSecret)
}
func (s *CredentialsController) GetCaCert(name, namespace string) (certInfo *credentials.CertInfo, err error) {
k8sSecret := s.secrets.Get(name, namespace)
if k8sSecret == nil {
strippedName := strings.TrimSuffix(name, securitymodel.SdsCaSuffix)
// Could not fetch cert, look for secret without -cacert suffix
k8sSecret := s.secrets.Get(strippedName, namespace)
if k8sSecret == nil {
return nil, fmt.Errorf("secret %v/%v not found", namespace, strippedName)
}
return ExtractRoot(k8sSecret.Data)
}
return ExtractRoot(k8sSecret.Data)
}View on GitHub (pinned to 8dc789c5cf)
Solutions
- Create the referenced secret in the correct namespace: kubectl create secret tls <name> -n <gateway-ns> --cert=... --key=...
- Verify name and namespace spelling against the Gateway's credentialName and the gateway's own namespace
- If just created, allow the informer a moment to sync; istiod will push the config once the secret appears (secret handlers re-trigger)
- For cross-namespace credentials remember the lookup is namespace-scoped — put the secret in the Gateway's namespace
Example fix
# before: Gateway references a missing secret credentialName: wildcard-tls # after: create it in the Gateway's namespace kubectl -n istio-system create secret tls wildcard-tls \ --cert=./tls.crt --key=./tls.key
Defensive patterns
Strategy: validation
Validate before calling
// Confirm the secret is present in the informer before pushing config.
if s.secrets.Get(name, namespace) == nil {
return nil, fmt.Errorf("secret %v/%v not found; refusing to reference it", namespace, name)
}
info, err := s.GetCertInfo(name, namespace) Prevention
- Create TLS secrets in the Gateway's namespace before applying the Gateway
- Use admission/CI checks that every credentialName resolves to an existing secret
- Remember lookups are namespace-scoped; place secrets where the gateway runs
When it happens
Trigger: A Gateway (or other consumer) references credentialName=<secret name> and the Secret is absent from the namespace istiod searches (typically the Gateway's own namespace or the configured credential namespace). Also transient when the Secret was just created and the informer has not synced it yet.
Common situations: cert-manager or manual TLS secret not yet created when the Gateway is applied; secret created in the wrong namespace (e.g. default instead of istio-system/gateway ns); typo in credentialName; secret deleted and the gateway config not updated.
Related errors
- %s/%s is not authorized to read secrets: %v
- found keys %q and %q, but they were empty
- found secret, but didn't have expected keys (%s and %s) or (
- found key %q, but it was empty
- found secret, but didn't have expected keys %s or %s; found:
AI-assisted analysis of istio/istio@8dc789c5cf (2026-08-15).
Data as JSON: /api/errors/c28c95deddca4a12.
Report an issue: GitHub.