{"record":{"id":"ee703557630a04a3","repo":"github/github-mcp-server","slug":"failed-to-download-logs-w","errorCode":null,"errorMessage":"failed to download logs: %w","messagePattern":"failed to download logs: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/github/actions.go","lineNumber":174,"sourceCode":"\t\tresult[\"message\"] = \"Job logs content retrieved successfully\"\n\t\tresult[\"original_length\"] = originalLength\n\t} else {\n\t\t// Return just the URL\n\t\tresult[\"logs_url\"] = url.String()\n\t\tresult[\"message\"] = \"Job logs are available for download\"\n\t\tresult[\"note\"] = \"The logs_url provides a download link for the individual job logs in plain text format. Use return_content=true to get the actual log content.\"\n\t}\n\n\treturn result, resp, nil\n}\n\nfunc downloadLogContent(ctx context.Context, logURL string, tailLines int, maxLines int) (string, int, *http.Response, error) {\n\tprof := profiler.New(nil, profiler.IsProfilingEnabled())\n\tfinish := prof.Start(ctx, \"log_buffer_processing\")\n\n\thttpResp, err := http.Get(logURL) //nolint:gosec\n\tif err != nil {\n\t\treturn \"\", 0, httpResp, fmt.Errorf(\"failed to download logs: %w\", err)\n\t}\n\tdefer func() { _ = httpResp.Body.Close() }()\n\n\tif httpResp.StatusCode != http.StatusOK {\n\t\treturn \"\", 0, httpResp, fmt.Errorf(\"failed to download logs: HTTP %d\", httpResp.StatusCode)\n\t}\n\n\tbufferSize := min(tailLines, maxLines)\n\n\tprocessedInput, totalLines, httpResp, err := buffer.ProcessResponseAsRingBufferToEnd(httpResp, bufferSize)\n\tif err != nil {\n\t\treturn \"\", 0, httpResp, fmt.Errorf(\"failed to process log content: %w\", err)\n\t}\n\n\tlines := strings.Split(processedInput, \"\\n\")\n\tif len(lines) > tailLines {\n\t\tlines = lines[len(lines)-tailLines:]\n\t}","sourceCodeStart":156,"sourceCodeEnd":192,"githubUrl":"https://github.com/github/github-mcp-server/blob/0ea1f775a7c73eff1bd2e25904d01136756bbfe2/pkg/github/actions.go#L156-L192","documentation":"Returned by downloadLogContent (pkg/github/actions.go:174) when http.Get(logURL) itself fails at the transport level - DNS resolution, TCP connect, TLS handshake, or connection reset before any response. Note it uses the default http.Client without the caller's context, so context cancellation surfaces as a transport error here rather than a clean ctx.Err().","triggerScenarios":"Fetching a signed objects.githubusercontent.com log URL when DNS fails, the connection is refused or reset, a TLS error occurs (including corporate MITM proxies with untrusted roots), or the environment has no egress to GitHub blob storage.","commonSituations":"Containers/CI runners without HTTPS proxy env vars set; corporate TLS interception with an internal CA not in the trust store; transient DNS flakiness; egress firewalls allowing api.github.com but blocking objects.githubusercontent.com.","solutions":["Check HTTP(S)_PROXY environment variables in containers that require an outbound proxy","Test reachability: curl -I <signed-url> from the same host","Add the corporate CA to the system trust store if TLS interception is in play","Retry - transport blips are usually transient, and each retry gets a fresh signed URL"],"exampleFix":"// before\nhttpResp, err := http.Get(logURL)\nif err != nil {\n    return \"\", 0, httpResp, fmt.Errorf(\"failed to download logs: %w\", err)\n}\n\n// after - honor context cancellation and make transport errors retryable\nreq, err := http.NewRequestWithContext(ctx, http.MethodGet, logURL, nil)\nif err != nil {\n    return \"\", 0, nil, fmt.Errorf(\"bad log URL: %w\", err)\n}\nhttpResp, err := httpClient.Do(req)\nif err != nil {\n    if errors.Is(err, context.Canceled) {\n        return \"\", 0, nil, err // caller abort, do not retry\n    }\n    return \"\", 0, nil, fmt.Errorf(\"failed to download logs (transient, retry): %w\", err)\n}","handlingStrategy":"retry","validationCode":"// Pre-flight the log host before the tool call\nif _, err := net.DialTimeout(\"tcp\", \"objects.githubusercontent.com:443\", 3*time.Second); err != nil {\n    return fmt.Errorf(\"no egress to log storage: %w\", err)\n}","typeGuard":null,"tryCatchPattern":"if err != nil {\n    var netErr net.Error\n    if errors.As(err, &netErr) {\n        time.Sleep(time.Second)\n        return retryOnce() // transient transport failure\n    }\n    if certErr := (&tls.CertificateVerificationError{}); errors.As(err, &certErr) {\n        return err // trust store problem: fix CA, do not retry\n    }\n    return err\n}","preventionTips":["Set HTTPS_PROXY/HTTP_PROXY in containerized deployments that need an outbound proxy","Install corporate CA certificates into the image trust store","Keep DNS resolvers healthy where the server runs","Retry transport errors once before escalating - most are transient"],"tags":["network","http","proxy","tls","go"],"backgroundTag":null,"analyzedSha":"0ea1f775a7c73eff1bd2e25904d01136756bbfe2","analyzedAt":"2026-08-15T18:10:19.804Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}