microg/GmsCore · error · IllegalStateException
missing payload
Error message
missing payload
What it means
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.
Source
Thrown at play-services-safetynet/core/src/main/java/org/microg/gms/safetynet/Attestation.java:148
} catch (Exception e) {
Log.w(TAG, e);
return null;
}
}
public static byte[][] getPackageSignatures(Context context, String packageName) throws Exception {
PackageInfo pi = context.getPackageManager().getPackageInfo(packageName, PackageManager.GET_SIGNATURES);
ArrayList<byte[]> res = new ArrayList<>();
MessageDigest digest = getSha256Digest();
for (Signature signature : pi.signatures) {
res.add(digest.digest(signature.toByteArray()));
}
return res.toArray(new byte[][]{});
}
public String attest(String apiKey) throws IOException {
if (payload == null) {
throw new IllegalStateException("missing payload");
}
return attest(new AttestRequest.Builder().safetyNetData(ByteString.of(payload)).droidGuardResult(droidGuardResult).build(), apiKey).result;
}
private AttestResponse attest(AttestRequest request, String apiKey) throws IOException {
ProfileManager.ensureInitialized(context);
String requestUrl = "https://www.googleapis.com/androidcheck/v1/attestations/attest?alt=PROTO&key=" + apiKey;
HttpURLConnection connection = (HttpURLConnection) new URL(requestUrl).openConnection();
connection.setRequestMethod("POST");
connection.setDoInput(true);
connection.setDoOutput(true);
connection.setRequestProperty("content-type", "application/x-protobuf");
connection.setRequestProperty("Accept-Encoding", "gzip");
connection.setRequestProperty("X-Android-Package", packageName);
connection.setRequestProperty("X-Android-Cert", PackageUtils.firstSignatureDigest(context, packageName));
connection.setRequestProperty("User-Agent", "SafetyNet/" + Constants.GMS_VERSION_CODE + " (" + Build.DEVICE + " " + Build.ID + "); gzip");
OutputStream os = connection.getOutputStream();View on GitHub (pinned to 157c9d86ac)
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
Example fix
// before Attestation attestation = new Attestation(context); String result = attestation.attest(apiKey); // throws // after Attestation attestation = new Attestation(context); attestation.setPayload(requestDataBytes); String result = attestation.attest(apiKey);
Defensive patterns
Strategy: validation
Validate before calling
// before calling attest
if (attestation.getPayload() == null) {
throw new IllegalArgumentException("attestation payload must be set before attest()");
} Try / catch
try {
String result = attestation.attest(apiKey);
} catch (IllegalStateException e) {
// payload missing: set payload and retry once
} Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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.
Understand the failure class
Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.
Related errors
AI-assisted analysis of microg/GmsCore@157c9d86ac (2026-09-06).
Data as JSON: /api/errors/0ac72f7086e1db6f.
Report an issue: GitHub.