{"record":{"id":"0ac72f7086e1db6f","repo":"microg/GmsCore","slug":"missing-payload","errorCode":null,"errorMessage":"missing payload","messagePattern":"missing payload","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"play-services-safetynet/core/src/main/java/org/microg/gms/safetynet/Attestation.java","lineNumber":148,"sourceCode":"        } catch (Exception e) {\n            Log.w(TAG, e);\n            return null;\n        }\n    }\n\n    public static byte[][] getPackageSignatures(Context context, String packageName) throws Exception {\n        PackageInfo pi = context.getPackageManager().getPackageInfo(packageName, PackageManager.GET_SIGNATURES);\n        ArrayList<byte[]> res = new ArrayList<>();\n        MessageDigest digest = getSha256Digest();\n        for (Signature signature : pi.signatures) {\n            res.add(digest.digest(signature.toByteArray()));\n        }\n        return res.toArray(new byte[][]{});\n    }\n\n    public String attest(String apiKey) throws IOException {\n        if (payload == null) {\n            throw new IllegalStateException(\"missing payload\");\n        }\n        return attest(new AttestRequest.Builder().safetyNetData(ByteString.of(payload)).droidGuardResult(droidGuardResult).build(), apiKey).result;\n    }\n\n    private AttestResponse attest(AttestRequest request, String apiKey) throws IOException {\n        ProfileManager.ensureInitialized(context);\n        String requestUrl = \"https://www.googleapis.com/androidcheck/v1/attestations/attest?alt=PROTO&key=\" + apiKey;\n        HttpURLConnection connection = (HttpURLConnection) new URL(requestUrl).openConnection();\n        connection.setRequestMethod(\"POST\");\n        connection.setDoInput(true);\n        connection.setDoOutput(true);\n        connection.setRequestProperty(\"content-type\", \"application/x-protobuf\");\n        connection.setRequestProperty(\"Accept-Encoding\", \"gzip\");\n        connection.setRequestProperty(\"X-Android-Package\", packageName);\n        connection.setRequestProperty(\"X-Android-Cert\", PackageUtils.firstSignatureDigest(context, packageName));\n        connection.setRequestProperty(\"User-Agent\", \"SafetyNet/\" + Constants.GMS_VERSION_CODE + \" (\" + Build.DEVICE + \" \" + Build.ID + \"); gzip\");\n\n        OutputStream os = connection.getOutputStream();","sourceCodeStart":130,"sourceCodeEnd":166,"githubUrl":"https://github.com/microg/GmsCore/blob/157c9d86ac46c195a86c2f15ab55c84036223f95/play-services-safetynet/core/src/main/java/org/microg/gms/safetynet/Attestation.java#L130-L166","documentation":"Attest.attest(String apiKey) requires a payload (the SafetyNet data to attest) to have been set on the Attestation object before calling. If payload is null, it throws IllegalStateException 'missing payload'. The payload is normally supplied via setPayload/setNonceSource or similar setters prior to attestation.","triggerScenarios":"Calling attest(apiKey) on an Attestation instance whose payload field was never set (or set to null), e.g. when building the request without SafetyNet data.","commonSituations":"Skipping the payload setup step (e.g. not calling setPayload with request data bytes) or constructing Attestation directly instead of via the documented builder flow in a SafetyNet attestation pipeline.","solutions":["Call setPayload (or the builder's safetyNetData) with non-null bytes before calling attest(apiKey)","Verify the code path that sets payload actually runs (e.g. nonce/request data generation did not fail silently)","Pass payload explicitly via AttestRequest.Builder().safetyNetData(ByteString.of(data)) using the private attest(AttestRequest, apiKey) path"],"exampleFix":"// before\nAttestation attestation = new Attestation(context);\nString result = attestation.attest(apiKey); // throws\n// after\nAttestation attestation = new Attestation(context);\nattestation.setPayload(requestDataBytes);\nString result = attestation.attest(apiKey);","handlingStrategy":"validation","validationCode":"// before calling attest\nif (attestation.getPayload() == null) {\n    throw new IllegalArgumentException(\"attestation payload must be set before attest()\");\n}","typeGuard":null,"tryCatchPattern":"try {\n    String result = attestation.attest(apiKey);\n} catch (IllegalStateException e) {\n    // payload missing: set payload and retry once\n}","preventionTips":["Always call setPayload with non-null data before attest(apiKey)","Use AttestRequest.Builder().safetyNetData(...) to make payload explicit","Assert payload presence in unit tests covering the attestation flow"],"tags":["safetynet","missing-payload","attestation"],"backgroundTag":"empty-required-field","analyzedSha":"157c9d86ac46c195a86c2f15ab55c84036223f95","analyzedAt":"2026-09-06T17:27:33.892Z","contentChangedAt":"2026-09-06T17:27:33.892Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}