{"record":{"id":"9ca315c4a53f37c1","repo":"SonarSource/sonarqube","slug":"supplied-date-format-for-parameter-s-is-wrong-pl","errorCode":null,"errorMessage":"Supplied date format for parameter %s is wrong. Please supply date in the ISO 8601 date format (YYYY-MM-DD)","messagePattern":"Supplied date format for parameter (.+?) is wrong\\. Please supply date in the ISO 8601 date format \\(YYYY-MM-DD\\)","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":400,"severity":"error","filePath":"server/sonar-webserver-webapi/src/main/java/org/sonar/server/usertoken/ws/GenerateAction.java","lineNumber":164,"sourceCode":"      .setName(request.mandatoryParam(PARAM_NAME).trim())\n      .setCreatedAt(system.now())\n      .setType(getTokenTypeFromRequest(request).name());\n    if (expirationDate != null) {\n      userTokenDtoFromRequest.setExpirationDate(expirationDate.atStartOfDay(ZoneOffset.UTC).toInstant().toEpochMilli());\n    }\n    setProjectFromRequest(dbSession, userTokenDtoFromRequest, request);\n    return userTokenDtoFromRequest;\n  }\n\n  @Nullable\n  private static LocalDate getExpirationDateFromRequest(Request request) {\n    String expirationDateString = request.param(PARAM_EXPIRATION_DATE);\n\n    if (expirationDateString != null) {\n      try {\n        return LocalDate.parse(expirationDateString, DateTimeFormatter.ISO_DATE);\n      } catch (DateTimeParseException e) {\n        throw new IllegalArgumentException(String.format(\"Supplied date format for parameter %s is wrong. Please supply date in the ISO 8601 \" +\n          \"date format (YYYY-MM-DD)\", PARAM_EXPIRATION_DATE));\n      }\n    }\n\n    return null;\n  }\n\n  private String generateToken(Request request, DbSession dbSession) {\n    TokenType tokenType = getTokenTypeFromRequest(request);\n    validateParametersCombination(userTokenSupport, dbSession, request, tokenType);\n    return tokenGenerator.generate(tokenType);\n  }\n\n  public void setProjectFromRequest(DbSession session, UserTokenDto token, Request request) {\n    if (!PROJECT_ANALYSIS_TOKEN.equals(getTokenTypeFromRequest(request))) {\n      return;\n    }\n","sourceCodeStart":146,"sourceCodeEnd":182,"githubUrl":"https://github.com/SonarSource/sonarqube/blob/184c821202192afc1c599fc912d0889b69fffa53/server/sonar-webserver-webapi/src/main/java/org/sonar/server/usertoken/ws/GenerateAction.java#L146-L182","documentation":"GenerateAction (api/user_tokens/generate) parses the optional expiration date with DateTimeFormatter.ISO_DATE and converts any DateTimeParseException into this IllegalArgumentException, telling the caller to supply an ISO 8601 date (YYYY-MM-DD). The raw parse failure detail is discarded in favor of this uniform message naming the offending parameter.","triggerScenarios":"POST api/user_tokens/generate with expiration_date values like '12/31/2026', '31-12-2026', '2026-12-31T00:00:00Z', 'next month', or containing whitespace.","commonSituations":"Shell scripts building dates with locale-dependent formats (MM/DD/YYYY); passing full timestamps instead of date-only; Excel/CSV exported dates; timezone-suffixed strings from other tools; JSON serializers emitting ISO datetime rather than ISO date.","solutions":["Send the date strictly as YYYY-MM-DD, e.g. expiration_date=2026-12-31.","Strip time and timezone parts if your source data is a timestamp (take the date portion).","Normalize in the calling script: date -d \"$raw\" +%F on GNU date, or DateTimeFormatter.ofPattern input handling before the call.","Omit the parameter entirely if no expiration is required (unless a max token lifetime policy forces one)."],"exampleFix":"// before\ncurl -su \"$TOKEN:\" -X POST 'https://sonar/api/user_tokens/generate?name=ci&expiration_date=12/31/2026'\n// after: ISO 8601 date only\nEXP=$(date -d '+30 days' +%F)\ncurl -su \"$TOKEN:\" -X POST \"https://sonar/api/user_tokens/generate?name=ci&expiration_date=$EXP\"","handlingStrategy":"validation","validationCode":"function isoDateOrNull(s) {\n  if (s == null) return null;\n  return /^\\d{4}-\\d{2}-\\d{2}$/.test(s.trim()) && !isNaN(Date.parse(s)) ? s.trim() : null;\n}\nconst exp = isoDateOrNull(rawExpirationDate);\nif (rawExpirationDate != null && exp === null) throw new Error(`expiration_date must be YYYY-MM-DD, got: ${rawExpirationDate}`);","typeGuard":"function isValidIsoDate(v) {\n  return typeof v === 'string' && /^\\d{4}-\\d{2}-\\d{2}$/.test(v) && !isNaN(Date.parse(v));\n}","tryCatchPattern":"try {\n  await generateToken(name, exp);\n} catch (e) {\n  if (e.status === 400 && /ISO 8601 date format/.test(e.message)) {\n    throw new Error(`expiration_date '${exp}' not ISO YYYY-MM-DD`);\n  }\n  throw e;\n}","preventionTips":["Format dates with date -d ... +%F or language-native ISO date formatters","Strip time/timezone components before sending","Beware locale-default date formats (MM/DD/YYYY) in scripts and spreadsheets","Omit expiration_date when no expiration is needed"],"tags":["sonarqube","rest-api","date-format","validation"],"backgroundTag":"invalid-date-format","analyzedSha":"184c821202192afc1c599fc912d0889b69fffa53","analyzedAt":"2026-09-09T12:23:51.573Z","contentChangedAt":"2026-09-09T12:23:51.573Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}