{"record":{"id":"9ffdf3580c5606e4","repo":"flowable/flowable-engine","slug":"error-exporting-picture-e-getmessage","errorCode":null,"errorMessage":"Error exporting picture: ${e.getMessage()}","messagePattern":"Error exporting picture: (.+?)","errorType":"http","errorClass":"FlowableException","httpStatus":500,"severity":"error","filePath":"modules/flowable-rest/src/main/java/org/flowable/rest/service/api/identity/UserPictureResource.java","lineNumber":79,"sourceCode":"    public ResponseEntity<byte[]> getUserPicture(@ApiParam(name = \"userId\") @PathVariable String userId) {\n        User user = getUserFromRequest(userId);\n        Picture userPicture = identityService.getUserPicture(user.getId());\n\n        if (userPicture == null) {\n            throw new FlowableObjectNotFoundException(\"The user with id '\" + user.getId() + \"' does not have a picture.\", Picture.class);\n        }\n\n        HttpHeaders responseHeaders = new HttpHeaders();\n        if (userPicture.getMimeType() != null) {\n            responseHeaders.set(\"Content-Type\", userPicture.getMimeType());\n        } else {\n            responseHeaders.set(\"Content-Type\", \"image/jpeg\");\n        }\n\n        try {\n            return new ResponseEntity<>(IOUtils.toByteArray(userPicture.getInputStream()), responseHeaders, HttpStatus.OK);\n        } catch (Exception e) {\n            throw new FlowableException(\"Error exporting picture: \" + e.getMessage(), e);\n        }\n    }\n\n    @ApiOperation(consumes = \"multipart/form-data\", value = \"Updating a user’s picture\", tags = {\n            \"Users\" },  notes = \"The request should be of type multipart/form-data. There should be a single file-part included with the binary value of the picture. On top of that, the following additional form-fields can be present:\\n\"\n                    + \"\\n\"\n                    + \"mimeType: Optional mime-type for the uploaded picture. If omitted, the default of image/jpeg is used as a mime-type for the picture.\",\n            code = 204)\n    @ApiImplicitParams({\n            @ApiImplicitParam(name = \"file\", dataType = \"file\", value = \"Picture to update\", paramType = \"form\", required = true)\n    })\n    @ApiResponses(value = {\n            @ApiResponse(code = 204, message = \"Indicates the user was found and the picture has been updated. The response-body is left empty intentionally.\"),\n            @ApiResponse(code = 404, message = \"Indicates the requested user was not found.\")\n    })\n    @PutMapping(value = \"/identity/users/{userId}/picture\", consumes = \"multipart/form-data\")\n    @ResponseStatus(HttpStatus.NO_CONTENT)\n    public void updateUserPicture(@ApiParam(name = \"userId\") @PathVariable String userId, HttpServletRequest request) {","sourceCodeStart":61,"sourceCodeEnd":97,"githubUrl":"https://github.com/flowable/flowable-engine/blob/d6d39ce1c69ff244f2d9dc6af756a9b95e865586/modules/flowable-rest/src/main/java/org/flowable/rest/service/api/identity/UserPictureResource.java#L61-L97","documentation":"FlowableException (generic runtime) thrown by getUserPicture when reading the picture bytes fails: IOUtils.toByteArray(userPicture.getInputStream()) raised an exception. The original exception is attached as the cause, and its message is appended to 'Error exporting picture: '. Unlike the not-found case, this indicates a problem retrieving/streaming stored picture data, e.g. an unreadable or corrupt blob.","triggerScenarios":"The picture exists but its InputStream cannot be read — blob missing from the underlying store (DB table ACT_GE_BYTEARRAY row gone), DB connection dropped mid-stream, corrupt/zero-length blob, or an I/O error reading the stream.","commonSituations":"Database maintenance/manually purged byte-array rows while user references remain; datasource or network failures between the REST app and the DB; partially failed picture uploads; custom IdentityService implementations whose getUserPicture returns a Picture backed by an unavailable stream.","solutions":["Inspect the 'cause' exception in the server log to find the underlying I/O/DB error.","Re-upload the user's picture via PUT identity/users/{userId}/picture to replace the corrupt/missing blob.","Verify database connectivity and that the byte-array storage (e.g. ACT_GE_BYTEARRAY) is intact; restore from backup if rows were purged.","Retry the request if the cause was a transient connection failure; check DB connection-pool health."],"exampleFix":"// server-side: refresh the broken picture\n// before: picture row missing/corrupt -> 500 Error exporting picture\n// after\nPUT /identity/users/jdoe/picture  (multipart/form-data)\nfile=@avatar.png\n// re-upload replaces the blob and GET .../picture succeeds","handlingStrategy":"retry","validationCode":"// cannot pre-validate server-side blob integrity; retry on 5xx:\nconst res = await fetch(url);\nif (res.status >= 500) retryWithBackoff(3);","typeGuard":null,"tryCatchPattern":"try {\n  const res = await fetch(`/identity/users/${userId}/picture`);\n  if (!res.ok) {\n    const msg = await res.text();\n    if (msg.includes('Error exporting picture')) {\n      // check server log cause; retry once for transient DB/IO errors,\n      // otherwise re-upload the picture (PUT .../picture)\n    }\n  }\n} catch (e) { /* network error */ }","preventionTips":["Never manually purge ACT_GE_BYTEARRAY rows without updating user references.","Monitor DB connectivity/pool health for the Flowable datasource.","Inspect the exception cause in server logs to separate transient IO errors from corrupt blobs.","Re-upload pictures after database restores or migrations."],"tags":["rest","io-error","picture","blob","flowable"],"backgroundTag":"file-read-failed","analyzedSha":"d6d39ce1c69ff244f2d9dc6af756a9b95e865586","analyzedAt":"2026-09-11T06:41:19.413Z","contentChangedAt":"2026-09-11T06:41:19.413Z","schemaVersion":2},"datasetVersion":"2026-09-18T11:17:12.947Z"}