{"record":{"id":"17ae5b1c498031a7","repo":"MHSanaei/3x-ui","slug":"github-api-returned-status-d-s-17ae5b","errorCode":null,"errorMessage":"GitHub API returned status %d: %s","messagePattern":"GitHub API returned status (.+?): (.+?)","errorType":"http","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/web/service/server.go","lineNumber":800,"sourceCode":"\tif reqErr != nil {\n\t\treturn nil, reqErr\n\t}\n\tresp, err := s.settingService.NewProxiedHTTPClient(10 * time.Second).Do(req)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tdefer resp.Body.Close()\n\n\t// Check HTTP status code - GitHub API returns object instead of array on error\n\tif resp.StatusCode != http.StatusOK {\n\t\tbodyBytes, _ := io.ReadAll(resp.Body)\n\t\tvar errorResponse struct {\n\t\t\tMessage string `json:\"message\"`\n\t\t}\n\t\tif json.Unmarshal(bodyBytes, &errorResponse) == nil && errorResponse.Message != \"\" {\n\t\t\treturn nil, fmt.Errorf(\"GitHub API error: %s\", errorResponse.Message)\n\t\t}\n\t\treturn nil, fmt.Errorf(\"GitHub API returned status %d: %s\", resp.StatusCode, resp.Status)\n\t}\n\n\tbuffer := bytes.NewBuffer(make([]byte, bufferSize))\n\tbuffer.Reset()\n\tif _, err := buffer.ReadFrom(resp.Body); err != nil {\n\t\treturn nil, err\n\t}\n\n\tvar releases []Release\n\tif err := json.Unmarshal(buffer.Bytes(), &releases); err != nil {\n\t\treturn nil, err\n\t}\n\n\tvar versions []string\n\tfor _, release := range releases {\n\t\ttagVersion := strings.TrimPrefix(release.TagName, \"v\")\n\t\ttagParts := strings.Split(tagVersion, \".\")\n\t\tif len(tagParts) != 3 {","sourceCodeStart":782,"sourceCodeEnd":818,"githubUrl":"https://github.com/MHSanaei/3x-ui/blob/ad32144c42455696ea9f14e12168beac3e25f5d2/internal/web/service/server.go#L782-L818","documentation":"Returned by the same release-list fetch when the response is non-200 but the body has no parseable \"message\" JSON field, so only the status code and resp.Status can be reported. Covers non-GitHub-shaped failures: proxy error pages, HTML block pages, 5xx bodies. Distinguishes transport-level rejection from GitHub's structured errors (which produce the 'GitHub API error' variant).","triggerScenarios":"An intercepting proxy answers api.github.com with a plain 502/503 HTML page; GitHub outage returning 5xx without a JSON envelope; a captive portal returning 302-followed HTML.","commonSituations":"Panels behind corporate proxies or in regions where api.github.com is filtered; transient GitHub incidents; misconfigured outbound proxy for the panel.","solutions":["curl -si https://api.github.com/repos/XTLS/Xray-core/releases from the host to see the raw status and body","Fix the panel's proxy settings (Settings → proxy) so the API is reachable, or bypass it","Retry during a GitHub incident after checking githubstatus.com"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"versions, err := svc.GetXrayVersions()\nif err != nil {\n    var statusErr = err // matches \"GitHub API returned status\"\n    if strings.Contains(statusErr.Error(), \"returned status 5\") {\n        return retryable(err) // 5xx is transient\n    }\n    return fatal(err)\n}\n","preventionTips":["Test egress to api.github.com (curl -si) before debugging deeper","Keep the panel's outbound proxy configuration correct for both api.github.com and githubusercontent.com","Retry only 5xx/429; treat 401/403 as configuration errors"],"tags":["github-api","network","xray-update"],"backgroundTag":null,"analyzedSha":"ad32144c42455696ea9f14e12168beac3e25f5d2","analyzedAt":"2026-08-15T11:13:23.905Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}