dapr/dapr · critical · VerificationError
failed to extract SPIFFE ID: %w
Error message
failed to extract SPIFFE ID: %w
What it means
verifyCertAppIdentity parsed the certificate chain but go-spiffe's x509svid.IDFromCert could not extract a SPIFFE ID from the leaf. Typically the leaf has no URI SAN (or a malformed one), meaning it is not a SPIFFE SVID at all — for example a plain TLS cert was used for workflow signing. Wrapped as 'signing certificate N: failed to extract SPIFFE ID' in the VerificationError.
Source
Thrown at pkg/runtime/wfengine/state/state.go:1203
if expectedNamespace == "" {
return errors.New("expectedNamespace must not be empty")
}
if len(certChainDER) == 0 {
return errors.New("certificate chain is empty")
}
certs, err := x509.ParseCertificates(certChainDER)
if err != nil {
return fmt.Errorf("failed to parse certificate chain: %w", err)
}
if len(certs) == 0 {
return errors.New("no certificates in chain")
}
leaf := certs[0]
spiffeID, err := x509svid.IDFromCert(leaf)
if err != nil {
return fmt.Errorf("failed to extract SPIFFE ID: %w", err)
}
// Validate the full SPIFFE path structure: /ns/<namespace>/<app-id>
// Split produces: ["", "ns", "<namespace>", "<app-id>"]
segments := strings.Split(spiffeID.Path(), "/")
if len(segments) != 4 || segments[0] != "" || segments[1] != "ns" || segments[2] == "" || segments[3] == "" {
return fmt.Errorf("SPIFFE ID %q does not match expected path format /ns/<namespace>/<app-id>", spiffeID)
}
certNamespace := segments[2]
certAppID := segments[3]
if certNamespace != expectedNamespace {
return fmt.Errorf("certificate SPIFFE ID namespace %q does not match expected namespace %q", certNamespace, expectedNamespace)
}
if certAppID != expectedAppID {
return fmt.Errorf("certificate SPIFFE ID app %q does not match expected app %q", certAppID, expectedAppID)
}
View on GitHub (pinned to 74ad417027)
Solutions
- Issue signing certificates as proper SPIFFE SVIDs (URI SAN spiffe://<trust-domain>/...) via the workload identity/sentry subsystem
- Re-create the workflow so it is signed by the SVID-based identity
- Verify the leaf really is the SVID and not an intermediate/CA placed first by mistake
Example fix
// before: plain TLS cert (no URI SAN) used as signing identity leaf := tlsCert.Leaf // CN=myapp, no SPIFFE URI SAN // after: obtain an SVID from the workload identity subsystem // leaf must carry URI SAN: spiffe://example.org/ns/production/orders svid := workloadAPI.FetchX509SVID()
Defensive patterns
Strategy: try-catch
Validate before calling
// ensure the signing identity is a real SVID before use
if _, err := x509svid.IDFromCert(leaf); err != nil {
return fmt.Errorf("signing cert is not a SPIFFE SVID (missing URI SAN): %w", err)
} Type guard
func isSPIFFEExtractionFailure(err error) bool {
var ver *wferrors.VerificationError
return errors.As(err, &ver) && strings.Contains(ver.Error(), "failed to extract SPIFFE ID")
} Try / catch
if err := loadAndVerify(); err != nil {
var ver *wferrors.VerificationError
if errors.As(err, &ver) && strings.Contains(ver.Error(), "failed to extract SPIFFE ID") {
// a non-SVID cert was used for signing: re-issue from the workload identity subsystem and recreate
}
return err
} Prevention
- Only use workload-identity-issued SVIDs for workflow signing, never plain TLS certs
- Add a CI check that signing certs carry a spiffe:// URI SAN
When it happens
Trigger: The leaf certificate in the stored chain lacks a valid spiffe:// URI SAN — issuing workflow signing certs from a CA that does not embed SPIFFE IDs, or using an ordinary TLS certificate as the signing identity.
Common situations: Custom/internal CA without SPIFFE support wired into the signing path instead of the workload identity system; cert rotation switching from SVIDs to plain certs; test setups using self-signed TLS certs.
Related errors
- SPIFFE ID %q does not match expected path format /ns/<namesp
- certificate SPIFFE ID namespace %q does not match expected n
- certificate SPIFFE ID app %q does not match expected app %q
- certificate chain is empty
- failed to absorb verified foreign cert into ext-sigcert: %w
AI-assisted analysis of dapr/dapr@74ad417027 (2026-08-16).
Data as JSON: /api/errors/22e40296f8edd783.
Report an issue: GitHub.