go-task/task · error
both --cert and --cert-key must be provided together
Error message
both --cert and --cert-key must be provided together
What it means
buildHTTPClient enforces that a TLS client certificate (--cert) and its key (--cert-key) are supplied as a pair. Providing exactly one of them is invalid because Go's tls.Config requires both to load a client certificate, so it errors before any HTTP request is made.
Source
Thrown at taskfile/node_http.go:32
"github.com/go-task/task/v3/errors"
"github.com/go-task/task/v3/internal/execext"
"github.com/go-task/task/v3/internal/filepathext"
)
// An HTTPNode is a node that reads a Taskfile from a remote location via HTTP.
type HTTPNode struct {
*baseNode
url *url.URL // stores url pointing actual remote file. (e.g. with Taskfile.yml)
client *http.Client // HTTP client with optional TLS configuration
}
// buildHTTPClient creates an HTTP client with optional TLS configuration.
// If no certificate options are provided, it returns http.DefaultClient.
func buildHTTPClient(insecure bool, caCert, cert, certKey string) (*http.Client, error) {
// Validate that cert and certKey are provided together
if (cert != "" && certKey == "") || (cert == "" && certKey != "") {
return nil, fmt.Errorf("both --cert and --cert-key must be provided together")
}
// If no TLS customization is needed, return the default client
if !insecure && caCert == "" && cert == "" {
return http.DefaultClient, nil
}
tlsConfig := &tls.Config{
InsecureSkipVerify: insecure, //nolint:gosec
}
// Load custom CA certificate if provided
if caCert != "" {
caCertData, err := os.ReadFile(caCert)
if err != nil {
return nil, fmt.Errorf("failed to read CA certificate: %w", err)
}
caCertPool := x509.NewCertPool()View on GitHub (pinned to 385e5ad92a)
Solutions
- Pass both flags together: --cert client.crt --cert-key client.key
- If you don't need client certs, remove both flags entirely
- Check the config file/env that feeds these flags to ensure both values are set
- Regenerate or locate the missing key matching the certificate
Example fix
# before task --cert ./client.crt -f https://example.com/Taskfile.yml # after task --cert ./client.crt --cert-key ./client.key -f https://example.com/Taskfile.yml
Defensive patterns
Strategy: validation
Validate before calling
if (cert == "") != (certKey == "") {
return fmt.Errorf("--cert and --cert-key must be provided together")
} Type guard
func hasCompleteClientCertPair(cert, certKey string) bool {
return (cert == "") == (certKey == "")
} Try / catch
node, err := taskfile.NewHTTPNode(..., cert, certKey, ...)
if err != nil {
if strings.Contains(err.Error(), "must be provided together") {
// surface flag guidance to the user or fall back to default client
}
return err
} Prevention
- Always pass --cert and --cert-key as a pair in scripts/wrappers
- Store both paths together in your task runner config
- Add a pre-flight check in wrapper scripts before invoking task
- Omit both flags when mTLS is not required
When it happens
Trigger: NewHTTPNode -> buildHTTPClient called with cert set and certKey empty, or certKey set and cert empty — e.g. invoking task with --cert but forgetting --cert-key (or vice versa) when fetching a remote Taskfile over HTTPS.
Common situations: Mutual-TLS setups where a user passes the client cert but forgets the key path; flags wired from config where only one of the two values was populated; copy-pasting examples that set only one flag.
Related errors
- failed to read CA certificate: %w
- failed to parse CA certificate
- task: --cert and --cert-key must be provided together
- task: Blank Arch value provided
- task: Multiple Arch values provided
AI-assisted analysis of go-task/task@385e5ad92a (2026-09-05).
Data as JSON: /api/errors/31c9ebfa00081e45.
Report an issue: GitHub.