hashicorp/terraform · error
failed to append certs
Error message
failed to append certs
What it means
In NestingList or NestingSet mode, if MaxItems is set (non-zero, meaning a hard upper bound) then MinItems must not exceed it. A floor above the ceiling is an impossible constraint. When MaxItems is 0 it means unbounded, so the check is skipped.
Solutions
- Ensure MinItems <= MaxItems when MaxItems != 0.
- Set MaxItems: 0 if you want no upper limit.
- Lower MinItems or raise MaxItems so the range is satisfiable.
Example fix
// before
"items": { Nesting: configschema.NestingList, MinItems: 5, MaxItems: 3 },
// after
"items": { Nesting: configschema.NestingList, MinItems: 3, MaxItems: 5 }, Defensive patterns
Strategy: validation
Validate before calling
// In NestingList/NestingSet, MinItems must not exceed MaxItems (when MaxItems != 0).
func validRange(nb *configschema.NestedBlock) bool {
switch nb.Nesting {
case configschema.NestingList, configschema.NestingSet:
return nb.MaxItems == 0 || nb.MinItems <= nb.MaxItems
}
return true
} Type guard
func minLteMax(min, max int) bool { return max == 0 || min <= max } Prevention
- Always order limits as MinItems <= MaxItems in schema literals.
- Set MaxItems: 0 for unbounded rather than a large number.
- Add a lint check in schema-builder code.
When it happens
Trigger: NestingList/NestingSet with MinItems: 5, MaxItems: 3. Guard at internal_validate.go:89 is `blockS.MinItems > blockS.MaxItems && blockS.MaxItems != 0`.
Common situations: Swapping min/max values when authoring the schema; computing limits from config where the floor overruns the cap; copy-paste from another block with different bounds.
Related errors
- invalid lock id
- cannot delete default state
- consul lock was lost
- missing state name
- workspaces not supported
AI-assisted analysis of hashicorp/terraform@d32a084675 (2026-08-11).
Data as JSON: /api/errors/8c3320675d8c03b5.
Report an issue: GitHub.
Appendix: source
Thrown at internal/backend/remote-state/http/backend.go:294
return fmt.Errorf("client_certificate_pem is set but client_private_key_pem is not")
}
if clientPrivateKeyPem != "" && clientCertificatePem == "" {
return fmt.Errorf("client_private_key_pem is set but client_certificate_pem is not")
}
// TLS configuration is needed; create an object and configure it
var tlsConfig tls.Config
client.HTTPClient.Transport.(*http.Transport).TLSClientConfig = &tlsConfig
if skipCertVerification {
// ignores TLS verification
tlsConfig.InsecureSkipVerify = true
}
if clientCACertificatePem != "" {
// trust servers based on a CA
tlsConfig.RootCAs = x509.NewCertPool()
if !tlsConfig.RootCAs.AppendCertsFromPEM([]byte(clientCACertificatePem)) {
return errors.New("failed to append certs")
}
}
if clientCertificatePem != "" && clientPrivateKeyPem != "" {
// attach a client certificate to the TLS handshake (aka mTLS)
certificate, err := tls.X509KeyPair([]byte(clientCertificatePem), []byte(clientPrivateKeyPem))
if err != nil {
return fmt.Errorf("cannot load client certificate: %w", err)
}
tlsConfig.Certificates = []tls.Certificate{certificate}
}
return nil
}
func (b *Backend) StateMgr(name string) (statemgr.Full, tfdiags.Diagnostics) {
var diags tfdiags.Diagnostics
if name != backend.DefaultStateName {View on GitHub (pinned to d32a084675)