{"record":{"id":"42d90a8ea62c5124","repo":"nextcloud/all-in-one","slug":"unexpected-response-from-desec-while-checking-doma","errorCode":null,"errorMessage":"Unexpected response from deSEC while checking domain ownership (HTTP {code}): {body}","messagePattern":"Unexpected response from deSEC while checking domain ownership \\(HTTP (.+?)\\): (.+?)","errorType":"exception","errorClass":"\\Exception","httpStatus":422,"severity":"error","filePath":"php/src/Desec/DesecManager.php","lineNumber":362,"sourceCode":"        try {\n            $res = $this->guzzleClient->get($this->configurationManager->desecApiBase . '/domains/' . $domain . '/', [\n                'headers' => ['Authorization' => 'Token ' . $token],\n            ]);\n        } catch (TransferException $e) {\n            throw new \\Exception('Could not reach the deSEC API: ' . $e->getMessage());\n        }\n\n        $code = $res->getStatusCode();\n\n        if ($code === 200) {\n            return true;\n        }\n\n        if ($code === 404) {\n            return false;\n        }\n\n        throw new \\Exception('Unexpected response from deSEC while checking domain ownership (HTTP ' . $code . '): ' . $res->getBody()->getContents());\n    }\n\n    /**\n     * Creates a wildcard CNAME rrset (*.domain → domain.) for a newly registered domain.\n     * Errors are logged but do not abort the overall registration.\n     */\n    private function createWildcardCname(string $token, string $domain): void {\n        try {\n            $res = $this->guzzleClient->post($this->configurationManager->desecApiBase . '/domains/' . $domain . '/rrsets/', [\n                'headers' => ['Authorization' => 'Token ' . $token],\n                'json'    => [\n                    'subname' => '*',\n                    'type'    => 'CNAME',\n                    'ttl'     => 3600,\n                    'records' => [$domain . '.'],\n                ],\n            ]);\n        } catch (TransferException $e) {","sourceCodeStart":344,"sourceCodeEnd":380,"githubUrl":"https://github.com/nextcloud/all-in-one/blob/6b788eec5e61733cf03ed380a3572e43ae3f11ce/php/src/Desec/DesecManager.php#L344-L380","documentation":"GET {desecApiBase}/domains/{domain}/ returned a status other than 200 (owned) or 404 (not owned) during the ownership check. Realistic codes: 401 (token expired or revoked between calls), 429 (rate limit), 5xx (deSEC incident). The raw body is embedded.","triggerScenarios":"The bearer token became invalid between the failed POST /domains/ and this GET (e.g. user reset the deSEC password, which revokes tokens); 429 or 5xx from the API.","commonSituations":"Long-lived token invalidated by a password change on desec.io; rate limiting after repeated attempts; desec.io instability.","solutions":["On 401, re-authenticate with loginAccount() to mint a fresh token and restart the flow","On 429, back off and retry the ownership check","Read the embedded body for the exact API message","Confirm the account password was not reset at desec.io mid-flow"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"// Verify the token is still live before the ownership-sensitive flow\n$res = $guzzle->get(\"$apiBase/domains/\", ['headers' => ['Authorization' => \"Token $token\"], 'http_errors' => false]);\nif ($res->getStatusCode() === 401) {\n    $token = $manager->loginAccount($email, $password); // mint a fresh token\n}","typeGuard":null,"tryCatchPattern":"try {\n    $manager->registerDomain($token, $slug);\n} catch (\\Exception $e) {\n    if (str_contains($e->getMessage(), 'checking domain ownership')) {\n        if (str_contains($e->getMessage(), '(HTTP 401)')) { $token = relogin(); return retry(); }\n        if (str_contains($e->getMessage(), '(HTTP 429)')) { scheduleRetry(30); return; }\n    }\n    throw $e;\n}","preventionTips":["Don't hold deSEC tokens across long waits — re-login before retrying a multi-step flow","Remember a desec.io password reset revokes existing tokens","Treat 401 on this GET as a token-liveness signal, not a domain fact"],"tags":["php","desec","http-status","token","domains"],"backgroundTag":"unexpected-http-status","analyzedSha":"6b788eec5e61733cf03ed380a3572e43ae3f11ce","analyzedAt":"2026-08-21T05:47:24.382Z","schemaVersion":2},"datasetVersion":"2026-08-21T11:28:35.574Z"}