larksuite/cli · error
invalid %s %q: must be an absolute path to a PEM file
Error message
invalid %s %q: must be an absolute path to a PEM file
What it means
The extra root CA path (CLI_CA_PATH) is empty after trimming or is a relative path. For security, the CLI only accepts an absolute path to a PEM file so the trust anchor cannot be resolved ambiguously relative to the working directory. applyExtraRootCA rejects anything that is not absolute.
Source
Thrown at internal/transport/tls_ca.go:27
"fmt"
"net/http"
"path/filepath"
"strings"
"github.com/larksuite/cli/internal/binding"
"github.com/larksuite/cli/internal/envvars"
"github.com/larksuite/cli/internal/vfs"
)
// applyExtraRootCA augments t with an additional PEM bundle used for configured proxy
// TLS interception.
func applyExtraRootCA(t *http.Transport, caPath string) error {
caPath = strings.TrimSpace(caPath)
if caPath == "" {
return nil
}
if !filepath.IsAbs(caPath) {
return fmt.Errorf("invalid %s %q: must be an absolute path to a PEM file", envvars.CliCAPath, caPath)
}
safeCAPath, err := binding.AssertSecurePath(binding.AuditParams{
TargetPath: caPath,
Label: envvars.CliCAPath,
AllowReadableByOthers: true,
})
if err != nil {
return fmt.Errorf("unsafe %s %q: %w", envvars.CliCAPath, caPath, err)
}
pemBytes, err := vfs.ReadFile(safeCAPath)
if err != nil {
return fmt.Errorf("failed to read %s %q: %w", envvars.CliCAPath, caPath, err)
}
// Augment the system trust store. Do NOT silently discard a SystemCertPool
// error: falling back to an empty pool would make this transport trust ONLY
// the extra CA (dropping all system roots), which narrows trust unexpectedly
// and could break TLS to legitimate endpoints. Fail closed instead.View on GitHub (pinned to 7fd6ef3c07)
Solutions
- Set CLI_CA_PATH to an absolute path, e.g. /etc/ssl/certs/corp-ca.pem.
- Convert a relative path with an absolute prefix: use "$(pwd)/ca.pem" or realpath.
- Ensure the target is an actual PEM-encoded certificate file readable by the CLI user.
Example fix
// before export LARKSUITE_CLI_CA_PATH="./certs/ca.pem" // after export LARKSUITE_CLI_CA_PATH="/etc/lark-cli/certs/ca.pem"
Defensive patterns
Strategy: validation
Validate before calling
p := strings.TrimSpace(os.Getenv("LARKSUITE_CLI_CA_PATH"))
if p != "" && !filepath.IsAbs(p) {
return fmt.Errorf("CA path must be absolute: %s", p)
} Prevention
- Always store the CA bundle at a fixed absolute location (e.g. /etc/lark-cli/ca.pem).
- Use $(realpath ca.pem) when generating config from relative paths.
- Pin the path in provisioning tooling rather than ad-hoc shell exports.
When it happens
Trigger: Setting CLI_CA_PATH to something like 'certs/ca.pem' or './ca.pem' and starting the CLI; ApplyToTransport -> applyExtraRootCA performs filepath.IsAbs and fails.
Common situations: Relative path from internal docs or a colleague's setup where the working directory differed; CI runners executing from an unexpected cwd; value pointing to a directory or non-PEM file instead of the CA bundle.
Related errors
- unsafe %s %q: %w
- failed to read %s %q: %w
- failed to load system cert pool for %s: %w
- invalid %s %q: no certificates parsed from PEM
- proxy plugin enabled but config is invalid: %w
AI-assisted analysis of larksuite/cli@7fd6ef3c07 (2026-09-04).
Data as JSON: /api/errors/a8c78f2549115793.
Report an issue: GitHub.