1Panel-dev/1Panel · error
create certificates pool: %v
Error message
create certificates pool: %v
What it means
Panic in agent/utils/ssl/acme.go initCertPool when LEGO_CA_CERTIFICATES is set but lego.CreateCertPool fails to build the pool from the listed files — files unreadable, not PEM, or the system pool request failed. It aborts ACME client construction at startup of the SSL flow.
Source
Thrown at agent/utils/ssl/acme.go:294
config.UserAgent = "1Panel"
config.HTTPClient = createHTTPClientWithProxy(proxyURL, proxyUser, proxyPassword)
config.Certificate.Timeout = 60 * time.Second
return config
}
func initCertPool() *x509.CertPool {
customCACertsPath := os.Getenv("LEGO_CA_CERTIFICATES")
if customCACertsPath == "" {
return nil
}
useSystemCertPool, _ := strconv.ParseBool(os.Getenv("LEGO_CA_SYSTEM_CERT_POOL"))
caCerts := strings.Split(customCACertsPath, string(os.PathListSeparator))
certPool, err := lego.CreateCertPool(caCerts, useSystemCertPool)
if err != nil {
panic(fmt.Sprintf("create certificates pool: %v", err))
}
return certPool
}
func createHTTPClientWithProxy(proxyURL, username, password string) *http.Client {
var proxyFunc func(*http.Request) (*url.URL, error)
if proxyURL != "" {
parsedURL, err := url.Parse(proxyURL)
if err != nil {
proxyFunc = http.ProxyFromEnvironment
} else {
if username != "" && password != "" {
parsedURL.User = url.UserPassword(username, password)
} else if username != "" {
parsedURL.User = url.User(username)
}
proxyFunc = http.ProxyURL(parsedURL)View on GitHub (pinned to 5ac7c80881)
Solutions
- Verify each path in LEGO_CA_CERTIFICATES exists and is a PEM bundle: openssl x509 -in <file> -noout -text
- Fix the env var (absolute paths, colon-separated on Linux) or unset it to use the default pool
- If LEGO_CA_SYSTEM_CERT_POOL=true, confirm the system trust store is readable in the container
Example fix
# before export LEGO_CA_CERTIFICATES=/etc/ssl/corp-ca.pem # file missing/invalid # after openssl x509 -in /etc/pki/corp/ca.pem -noout # verify, then export LEGO_CA_CERTIFICATES=/etc/pki/corp/ca.pem
Defensive patterns
Strategy: validation
Validate before calling
if [ -n "$LEGO_CA_CERTIFICATES" ]; then
IFS=":" read -ra parts <<< "$LEGO_CA_CERTIFICATES"
for p in "${parts[@]}"; do openssl x509 -in "$p" -noout || exit 1; done
fi Prevention
- Validate LEGO_CA_CERTIFICATES files with openssl before exporting the var
- Use absolute paths and confirm CA mounts exist inside containers that run ACME
When it happens
Trigger: Set env LEGO_CA_CERTIFICATES=/path/ca.pem (possibly with LEGO_CA_SYSTEM_CERT_POOL=true); the path is wrong, the file is not valid PEM, or a listed entry is a directory — CreateCertPool returns err and initCertPool panics.
Common situations: Corporate MITM proxy CA installed for ACME calls; typo in the env var; PEM file exported with headers/base64 damage; container where the CA mount is missing.
Understand the failure class
- SSL/TLS and certificate errors — how TLS handshakes and certificate validation fail.
Related errors
- Fatal error config file: %s \n
- init db dir failed, err: %v
- init %s db file failed, err: %v
- no enough parameter for location
- unexpected end of file while scanning a string, maybe an unc
AI-assisted analysis of 1Panel-dev/1Panel@5ac7c80881 (2026-08-15).
Data as JSON: /api/errors/b7b28f07fb1564d5.
Report an issue: GitHub.