Hot off the Presses: Hub 3.14.0 now available

Hi everyone,

Edit: updated this post for the general release

I’m a developer on the Hub team, and we’re proud to announce an exciting new release for you in the beta channel. The team has been working tirelessly over the past few weeks to bring you new features and bug fixes.

The new version, 3.14.0, will be rolling out shortly.

We’ve tested this version extensively, but we encourage you to report any issues you find here or in our new bug reporter. Thanks for your help!

What’s New

  • New User Onboarding: A guided flow to help new users get started is now being rolled out to a limited number of users.
  • Unity Notification Service (UNS): The Hub is now integrated with UNS, allowing you to receive notifications from your Unity workspaces, including OS popups and app icon badges (OFF by default).
  • New Bug Reporter: Introduced a completely new Bug Reporter with an improved user interface, dark theme support, and automatic pre-filling of the user’s email.

General:

  • Licensing management is now a dedicated page accessible from the main navigation menu.
  • Updated the end-user messaging related to licensing for improved clarity.

Settings:

  • Added a keyboard shortcut (Cmd/Ctrl + ,) to open the Settings dialog.
  • The Hub version is now displayed in the header of the Settings dialog.
  • Added an option to configure the maximum number of concurrent downloads.

Installs:

  • The command-line interface (CLI) now correctly displays Editor versions built for Apple silicon.
  • Refactored the Editor and module installer on macOS to increase reliability and performance.

Bug fixes & improvements

Projects:

  • Fixed a bug in the “New Project” page where the character limit for the project path did not update correctly when changing the project template.
  • Fixed an issue where the Hub would incorrectly reuse command-line arguments when reopening a project that was already open in the Editor.

Installs:

  • The Hub now correctly remembers the user’s preference to not install Visual Studio when installing or updating an Editor.
  • Fixed a bug where selecting only “OpenJDK” or “Android SDK & NDK Tools” would incorrectly select all available Android components.
  • Fixed an issue where the selected module was not correctly focused in the “Add modules” window after triggering the install.
  • Fixed a bug where the module list in the “Add modules” window would not refresh correctly under certain conditions.

General:

  • Fixed an issue where the Hub could get stuck during the uninstall process if the User Account Control (UAC) prompt was declined on Windows.
  • Fixed an issue on Linux where the Unity Licensing Client was installed with incorrect root ownership and permissions.
  • Bug reports now correctly reflect the user’s license type.
  • Fixed unoptimized dependencies to decrease app size by 30%.
10 Likes

Nice! Well done

1 Like

I’d like to see the ability to launch a project straight into a Build Profile. I appreciate the platform drop-down, but it’s a bit of a pain launching into a platform, and then switching to a Build Profile. The editor has the -activeBuildProfile command line argument already and seems to launch into the last-active build profile. I guess the issue might be that the hub doesn’t know where Build Profile assets actually live?

Thanks,
Joe

I think hub should just remove “current platform” in dropdown option and instead just show the actual current platform

After upgrading, I am no longer able to sign in on linux!

I have tried clearing my browser cache(firefox), all Unity configs, reinstalling unityhub and redownloading it, nothing works :(.

There’s some errors in here that don’t look great (mostly about encryption?): last couple look interesting: ```
{“timestamp”:“2025-08-19T21:07:14.924Z”,“level”:“error”,“moduleName”:“Authentication Service”,“pid”:37495,“message”:“Error fetching user info from access token: Error: Error while encrypting the text provided to safeStorage.encryptString. Encryption is not available.”}
{“timestamp”:“2025-08-19T21:07:14.924Z”,“level”:“info”,“moduleName”:“LicensingSdkService”,“pid”:37495,“message”:“checkEntitlements: checking entitlements for: com.unity.editor.ui”}


```{"timestamp":"2025-08-19T21:07:13.994Z","level":"error","moduleName":"Authentication Service","pid":37495,"message":"{ status: 400, headers: Object [AxiosHeaders] { vary: 'Accept-Encoding', 'cache-control': 'no-cache, no-store, must-revalidate', pragma: 'no-cache', expires: '0', 'sc-request-id': '37d89ddf-c0e6-4529-8149-ef9db11e35e1', 'content-type': 'application/json', via: '1.1 google', date: 'Tue, 19 Aug 2025 21:07:13 GMT', 'alt-svc': 'h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000', 'transfer-encoding': 'chunked', 'google-accounts-check-oauth-login': 'true', 'strict-transport-security': 'max-age=31536000; includeSubDomains; preload;', connection: 'close' }, config: {}, data: { message: 'Input Error', code: '132.001', details: [ [Object] ] } }"}
{"timestamp":"2025-08-19T21:07:13.994Z","level":"warn","moduleName":"Authentication Service","pid":37495,"message":"Could not authenticate user SafeAxiosError: Request failed with status code 400\n    at #t (file:///opt/unityhub/resources/app.asar/build/main/services/networkInterceptors/networkInterceptors.js:1:969)\n    at file:///opt/unityhub/resources/app.asar/build/main/services/networkInterceptors/networkInterceptors.js:1:782\n    at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n    at async Axios.request (file:///opt/unityhub/resources/app.asar/node_modules/axios/lib/core/Axios.js:40:14)\n    at async AuthService.authenticateUser (file:///opt/unityhub/resources/app.asar/build/main/services/authService/AuthService.js:1:7531)\n    at async AuthService.handleLoginUrl (file:///opt/unityhub/resources/app.asar/build/main/services/authService/AuthService.js:1:14489) {\n  response: { status: 400, statusText: 'Bad Request', data: { message: 'Input Error', code: '132.001', details: [Array] }, headers: Object [AxiosHeaders] { vary: 'Accept-Encoding', 'cache-control': 'no-cache, no-store, must-revalidate', pragma: 'no-cache', expires: '0', 'sc-request-id': '37d89ddf-c0e6-4529-8149-ef9db11e35e1', 'content-type': 'application/json', via: '1.1 google', date: 'Tue, 19 Aug 2025 21:07:13 GMT', 'alt-svc': 'h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000', 'transfer-encoding': 'chunked', 'google-accounts-check-oauth-login': 'true', 'strict-transport-security': 'max-age=31536000; includeSubDomains; preload;', connection: 'close' }, request: { path: '/v1/oauth2/token', method: 'POST', host: 'api.unity.com', protocol: 'https:' } },\n  [cause]: AxiosError: Request failed with status code 400\n      at settle (file:///opt/unityhub/resources/app.asar/node_modules/axios/lib/core/settle.js:19:12)\n      at Unzip.handleStreamEnd (file:///opt/unityhub/resources/app.asar/node_modules/axios/lib/adapters/http.js:599:11)\n      at Unzip.emit (node:events:530:35)\n      at Unzip.emit (node:domain:489:12)\n      at endReadableNT (node:internal/streams/readable:1698:12)\n      at process.processTicksAndRejections (node:internal/process/task_queues:90:21) {\n    code: 'ERR_BAD_REQUEST',\n    config: { transitional: [Object], adapter: [Array], transformRequest: [Array], transformResponse: [Array], timeout: 0, xsrfCookieName: 'XSRF-TOKEN', xsrfHeaderName: 'X-XSRF-TOKEN', maxContentLength: -1, maxBodyLength: -1, env: [Object], validateStatus: [Function: validateStatus], headers: [Object [AxiosHeaders]], proxy: false, method: 'post', url: 'https://api.unity.com/v1/oauth2/token', data: 'redirect_uri=unityhub%3A%2F%2Flogin&code_verifier=TNNsjt4PZ0OeALtVNktMlFQE5sBphMTpbTTucWTstqH1glGJSGkGI3Q5wZysfacGVzJvF6cb7sgPhe9Fii4DynXYQGFdr2ahhE2k&code=Ybvay9zbIh-PCzBlwMrXbg002f&client_id=unity_hub&grant_type=authorization_code', allowAbsoluteUrls: true },\n    request: ClientRequest { _events: [Object: null prototype], _eventsCount: 7, _maxListeners: undefined, outputData: [], outputSize: 0, writable: true, destroyed: true, _last: true, chunkedEncoding: false, shouldKeepAlive: false, maxRequestsOnConnectionReached: false, _defaultKeepAlive: true, useChunkedEncodingByDefault: true, sendDate: false, _removedConnection: false, _removedContLen: false, _removedTE: false, strictContentLength: false, _contentLength: 232, _hasBody: true, _trailer: '', finished: true, _headerSent: true, _closed: true, _header: 'POST /v1/oauth2/token HTTP/1.1\\r\\nAccept: application/json, text/plain, */*\\r\\nContent-Type: application/x-www-form-urlencoded\\r\\nUser-Agent: axios/1.11.0\\r\\nContent-Length: 232\\r\\nAccept-Encoding: gzip, compress, deflate, br\\r\\nHost: api.unity.com\\r\\nConnection: close\\r\\n\\r\\n', _keepAliveTimeout: 0, _onPendingData: [Function: nop], agent: [BoundHttpsProxyAgent], socketPath: undefined, method: 'POST', maxHeaderSize: undefined, insecureHTTPParser: undefined, joinDuplicateHeaders: undefined, path: '/v1/oauth2/token', _ended: true, res: [IncomingMessage], aborted: false, timeoutCb: null, upgradeOrConnect: false, parser: null, maxHeadersCount: null, reusedSocket: false, host: 'api.unity.com', protocol: 'https:', _redirectable: [Writable], [Symbol(shapeMode)]: false, [Symbol(kCapture)]: false, [Symbol(kBytesWritten)]: 0, [Symbol(kNeedDrain)]: false, [Symbol(corked)]: 0, [Symbol(kChunkedBuffer)]: [], [Symbol(kChunkedLength)]: 0, [Symbol(kSocket)]: [TLSSocket], [Symbol(kOutHeaders)]: [Object: null prototype], [Symbol(errored)]: null, [Symbol(kHighWaterMark)]: 65536, [Symbol(kRejectNonStandardBodyWrites)]: false, [Symbol(kUniqueHeaders)]: null },\n    response: { status: 400, statusText: 'Bad Request', headers: [Object [AxiosHeaders]], config: [Object], request: [ClientRequest], data: [Object] },\n    status: 400\n  }\n}"}
{"timestamp":"2025-08-19T21:07:13.990Z","level":"info","moduleName":"secondAppInstanceBootstrap","pid":43011,"message":"Second instance of the Hub was started. Closing..."}
{"timestamp":"2025-08-19T21:07:14.171Z","level":"error","moduleName":"Authentication Service","pid":37495,"message":"{ status: 400, headers: Object [AxiosHeaders] { vary: 'Accept-Encoding', 'cache-control': 'no-cache, no-store, must-revalidate', pragma: 'no-cache', expires: '0', 'sc-request-id': 'c5c40713-e7e2-47dc-90da-ab346e5c5893', 'content-type': 'application/json', via: '1.1 google', date: 'Tue, 19 Aug 2025 21:07:14 GMT', 'alt-svc': 'h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000', 'transfer-encoding': 'chunked', 'google-accounts-check-oauth-login': 'true', 'strict-transport-security': 'max-age=31536000; includeSubDomains; preload;', connection: 'close' }, config: {}, data: { message: 'Input Error', code: '132.001', details: [ [Object] ] } }"}
{"timestamp":"2025-08-19T21:07:14.171Z","level":"warn","moduleName":"Authentication Service","pid":37495,"message":"Could not authenticate user SafeAxiosError: Request failed with status code 400\n    at #t (file:///opt/unityhub/resources/app.asar/build/main/services/networkInterceptors/networkInterceptors.js:1:969)\n    at file:///opt/unityhub/resources/app.asar/build/main/services/networkInterceptors/networkInterceptors.js:1:782\n    at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n    at async Axios.request (file:///opt/unityhub/resources/app.asar/node_modules/axios/lib/core/Axios.js:40:14)\n    at async AuthService.authenticateUser (file:///opt/unityhub/resources/app.asar/build/main/services/authService/AuthService.js:1:7531)\n    at async AuthService.handleLoginUrl (file:///opt/unityhub/resources/app.asar/build/main/services/authService/AuthService.js:1:14489) {\n  response: { status: 400, statusText: 'Bad Request', data: { message: 'Input Error', code: '132.001', details: [Array] }, headers: Object [AxiosHeaders] { vary: 'Accept-Encoding', 'cache-control': 'no-cache, no-store, must-revalidate', pragma: 'no-cache', expires: '0', 'sc-request-id': 'c5c40713-e7e2-47dc-90da-ab346e5c5893', 'content-type': 'application/json', via: '1.1 google', date: 'Tue, 19 Aug 2025 21:07:14 GMT', 'alt-svc': 'h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000', 'transfer-encoding': 'chunked', 'google-accounts-check-oauth-login': 'true', 'strict-transport-security': 'max-age=31536000; includeSubDomains; preload;', connection: 'close' }, request: { path: '/v1/oauth2/token', method: 'POST', host: 'api.unity.com', protocol: 'https:' } },\n  [cause]: AxiosError: Request failed with status code 400\n      at settle (file:///opt/unityhub/resources/app.asar/node_modules/axios/lib/core/settle.js:19:12)\n      at Unzip.handleStreamEnd (file:///opt/unityhub/resources/app.asar/node_modules/axios/lib/adapters/http.js:599:11)\n      at Unzip.emit (node:events:530:35)\n      at Unzip.emit (node:domain:489:12)\n      at endReadableNT (node:internal/streams/readable:1698:12)\n      at process.processTicksAndRejections (node:internal/process/task_queues:90:21) {\n    code: 'ERR_BAD_REQUEST',\n    config: { transitional: [Object], adapter: [Array], transformRequest: [Array], transformResponse: [Array], timeout: 0, xsrfCookieName: 'XSRF-TOKEN', xsrfHeaderName: 'X-XSRF-TOKEN', maxContentLength: -1, maxBodyLength: -1, env: [Object], validateStatus: [Function: validateStatus], headers: [Object [AxiosHeaders]], proxy: false, method: 'post', url: 'https://api.unity.com/v1/oauth2/token', data: 'redirect_uri=unityhub%3A%2F%2Flogin&code_verifier=TNNsjt4PZ0OeALtVNktMlFQE5sBphMTpbTTucWTstqH1glGJSGkGI3Q5wZysfacGVzJvF6cb7sgPhe9Fii4DynXYQGFdr2ahhE2k&code=cpFKxa3AR4At5dui-99jgA002f&client_id=unity_hub&grant_type=authorization_code', allowAbsoluteUrls: true },\n    request: ClientRequest { _events: [Object: null prototype], _eventsCount: 7, _maxListeners: undefined, outputData: [], outputSize: 0, writable: true, destroyed: true, _last: true, chunkedEncoding: false, shouldKeepAlive: false, maxRequestsOnConnectionReached: false, _defaultKeepAlive: true, useChunkedEncodingByDefault: true, sendDate: false, _removedConnection: false, _removedContLen: false, _removedTE: false, strictContentLength: false, _contentLength: 232, _hasBody: true, _trailer: '', finished: true, _headerSent: true, _closed: true, _header: 'POST /v1/oauth2/token HTTP/1.1\\r\\nAccept: application/json, text/plain, */*\\r\\nContent-Type: application/x-www-form-urlencoded\\r\\nUser-Agent: axios/1.11.0\\r\\nContent-Length: 232\\r\\nAccept-Encoding: gzip, compress, deflate, br\\r\\nHost: api.unity.com\\r\\nConnection: close\\r\\n\\r\\n', _keepAliveTimeout: 0, _onPendingData: [Function: nop], agent: [BoundHttpsProxyAgent], socketPath: undefined, method: 'POST', maxHeaderSize: undefined, insecureHTTPParser: undefined, joinDuplicateHeaders: undefined, path: '/v1/oauth2/token', _ended: true, res: [IncomingMessage], aborted: false, timeoutCb: null, upgradeOrConnect: false, parser: null, maxHeadersCount: null, reusedSocket: false, host: 'api.unity.com', protocol: 'https:', _redirectable: [Writable], [Symbol(shapeMode)]: false, [Symbol(kCapture)]: false, [Symbol(kBytesWritten)]: 0, [Symbol(kNeedDrain)]: false, [Symbol(corked)]: 0, [Symbol(kChunkedBuffer)]: [], [Symbol(kChunkedLength)]: 0, [Symbol(kSocket)]: [TLSSocket], [Symbol(kOutHeaders)]: [Object: null prototype], [Symbol(errored)]: null, [Symbol(kHighWaterMark)]: 65536, [Symbol(kRejectNonStandardBodyWrites)]: false, [Symbol(kUniqueHeaders)]: null },\n    response: { status: 400, statusText: 'Bad Request', headers: [Object [AxiosHeaders]], config: [Object], request: [ClientRequest], data: [Object] },\n    status: 400\n  }\n}"}
{"timestamp":"2025-08-19T21:07:14.186Z","level":"info","moduleName":"Bootstrap","pid":43058,"message":"Hub start : SecondAppInstance"}
{"timestamp":"2025-08-19T21:07:14.186Z","level":"info","moduleName":"secondAppInstanceBootstrap","pid":43058,"message":"Second instance of the Hub was started. Closing..."}
{"timestamp":"2025-08-19T21:07:14.295Z","level":"error","moduleName":"Authentication Service","pid":37495,"message":"{ status: 400, headers: Object [AxiosHeaders] { vary: 'Accept-Encoding', 'cache-control': 'no-cache, no-store, must-revalidate', pragma: 'no-cache', expires: '0', 'sc-request-id': 'e254d73c-9cd0-44df-bcb4-f5ae84e150e5', 'content-type': 'application/json', via: '1.1 google', date: 'Tue, 19 Aug 2025 21:07:14 GMT', 'alt-svc': 'h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000', 'transfer-encoding': 'chunked', 'google-accounts-check-oauth-login': 'true', 'strict-transport-security': 'max-age=31536000; includeSubDomains; preload;', connection: 'close' }, config: {}, data: { message: 'Input Error', code: '132.001', details: [ [Object] ] } }"}
{"timestamp":"2025-08-19T21:07:14.295Z","level":"warn","moduleName":"Authentication Service","pid":37495,"message":"Could not authenticate user SafeAxiosError: Request failed with status code 400\n    at #t (file:///opt/unityhub/resources/app.asar/build/main/services/networkInterceptors/networkInterceptors.js:1:969)\n    at file:///opt/unityhub/resources/app.asar/build/main/services/networkInterceptors/networkInterceptors.js:1:782\n    at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n    at async Axios.request (file:///opt/unityhub/resources/app.asar/node_modules/axios/lib/core/Axios.js:40:14)\n    at async AuthService.authenticateUser (file:///opt/unityhub/resources/app.asar/build/main/services/authService/AuthService.js:1:7531)\n    at async AuthService.handleLoginUrl (file:///opt/unityhub/resources/app.asar/build/main/services/authService/AuthService.js:1:14489) {\n  response: { status: 400, statusText: 'Bad Request', data: { message: 'Input Error', code: '132.001', details: [Array] }, headers: Object [AxiosHeaders] { vary: 'Accept-Encoding', 'cache-control': 'no-cache, no-store, must-revalidate', pragma: 'no-cache', expires: '0', 'sc-request-id': 'e254d73c-9cd0-44df-bcb4-f5ae84e150e5', 'content-type': 'application/json', via: '1.1 google', date: 'Tue, 19 Aug 2025 21:07:14 GMT', 'alt-svc': 'h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000', 'transfer-encoding': 'chunked', 'google-accounts-check-oauth-login': 'true', 'strict-transport-security': 'max-age=31536000; includeSubDomains; preload;', connection: 'close' }, request: { path: '/v1/oauth2/token', method: 'POST', host: 'api.unity.com', protocol: 'https:' } },\n  [cause]: AxiosError: Request failed with status code 400\n      at settle (file:///opt/unityhub/resources/app.asar/node_modules/axios/lib/core/settle.js:19:12)\n      at Unzip.handleStreamEnd (file:///opt/unityhub/resources/app.asar/node_modules/axios/lib/adapters/http.js:599:11)\n      at Unzip.emit (node:events:530:35)\n      at Unzip.emit (node:domain:489:12)\n      at endReadableNT (node:internal/streams/readable:1698:12)\n      at process.processTicksAndRejections (node:internal/process/task_queues:90:21) {\n    code: 'ERR_BAD_REQUEST',\n    config: { transitional: [Object], adapter: [Array], transformRequest: [Array], transformResponse: [Array], timeout: 0, xsrfCookieName: 'XSRF-TOKEN', xsrfHeaderName: 'X-XSRF-TOKEN', maxContentLength: -1, maxBodyLength: -1, env: [Object], validateStatus: [Function: validateStatus], headers: [Object [AxiosHeaders]], proxy: false, method: 'post', url: 'https://api.unity.com/v1/oauth2/token', data: 'redirect_uri=unityhub%3A%2F%2Flogin&code_verifier=TNNsjt4PZ0OeALtVNktMlFQE5sBphMTpbTTucWTstqH1glGJSGkGI3Q5wZysfacGVzJvF6cb7sgPhe9Fii4DynXYQGFdr2ahhE2k&code=bNlUAQM0dF1jt0d1ChFDjw002f&client_id=unity_hub&grant_type=authorization_code', allowAbsoluteUrls: true },\n    request: ClientRequest { _events: [Object: null prototype], _eventsCount: 7, _maxListeners: undefined, outputData: [], outputSize: 0, writable: true, destroyed: true, _last: true, chunkedEncoding: false, shouldKeepAlive: false, maxRequestsOnConnectionReached: false, _defaultKeepAlive: true, useChunkedEncodingByDefault: true, sendDate: false, _removedConnection: false, _removedContLen: false, _removedTE: false, strictContentLength: false, _contentLength: 232, _hasBody: true, _trailer: '', finished: true, _headerSent: true, _closed: true, _header: 'POST /v1/oauth2/token HTTP/1.1\\r\\nAccept: application/json, text/plain, */*\\r\\nContent-Type: application/x-www-form-urlencoded\\r\\nUser-Agent: axios/1.11.0\\r\\nContent-Length: 232\\r\\nAccept-Encoding: gzip, compress, deflate, br\\r\\nHost: api.unity.com\\r\\nConnection: close\\r\\n\\r\\n', _keepAliveTimeout: 0, _onPendingData: [Function: nop], agent: [BoundHttpsProxyAgent], socketPath: undefined, method: 'POST', maxHeaderSize: undefined, insecureHTTPParser: undefined, joinDuplicateHeaders: undefined, path: '/v1/oauth2/token', _ended: true, res: [IncomingMessage], aborted: false, timeoutCb: null, upgradeOrConnect: false, parser: null, maxHeadersCount: null, reusedSocket: false, host: 'api.unity.com', protocol: 'https:', _redirectable: [Writable], [Symbol(shapeMode)]: false, [Symbol(kCapture)]: false, [Symbol(kBytesWritten)]: 0, [Symbol(kNeedDrain)]: false, [Symbol(corked)]: 0, [Symbol(kChunkedBuffer)]: [], [Symbol(kChunkedLength)]: 0, [Symbol(kSocket)]: [TLSSocket], [Symbol(kOutHeaders)]: [Object: null prototype], [Symbol(errored)]: null, [Symbol(kHighWaterMark)]: 65536, [Symbol(kRejectNonStandardBodyWrites)]: false, [Symbol(kUniqueHeaders)]: null },\n    response: { status: 400, statusText: 'Bad Request', headers: [Object [AxiosHeaders]], config: [Object], request: [ClientRequest], data: [Object] },\n    status: 400\n  }\n}"}
{"timestamp":"2025-08-19T21:07:14.304Z","level":"info","moduleName":"Bootstrap","pid":43103,"message":"Hub start : SecondAppInstance"}
{"timestamp":"2025-08-19T21:07:14.305Z","level":"info","moduleName":"secondAppInstanceBootstrap","pid":43103,"message":"Second instance of the Hub was started. Closing..."}
{"timestamp":"2025-08-19T21:07:14.411Z","level":"error","moduleName":"Authentication Service","pid":37495,"message":"{ status: 400, headers: Object [AxiosHeaders] { vary: 'Accept-Encoding', 'cache-control': 'no-cache, no-store, must-revalidate', pragma: 'no-cache', expires: '0', 'sc-request-id': 'b77f6861-20aa-4060-ac86-9f5033791fdb', 'content-type': 'application/json', via: '1.1 google', date: 'Tue, 19 Aug 2025 21:07:13 GMT', 'alt-svc': 'h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000', 'transfer-encoding': 'chunked', 'google-accounts-check-oauth-login': 'true', 'strict-transport-security': 'max-age=31536000; includeSubDomains; preload;', connection: 'close' }, config: {}, data: { message: 'Input Error', code: '132.001', details: [ [Object] ] } }"}
{"timestamp":"2025-08-19T21:07:14.411Z","level":"warn","moduleName":"Authentication Service","pid":37495,"message":"Could not authenticate user SafeAxiosError: Request failed with status code 400\n    at #t (file:///opt/unityhub/resources/app.asar/build/main/services/networkInterceptors/networkInterceptors.js:1:969)\n    at file:///opt/unityhub/resources/app.asar/build/main/services/networkInterceptors/networkInterceptors.js:1:782\n    at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n    at async Axios.request (file:///opt/unityhub/resources/app.asar/node_modules/axios/lib/core/Axios.js:40:14)\n    at async AuthService.authenticateUser (file:///opt/unityhub/resources/app.asar/build/main/services/authService/AuthService.js:1:7531)\n    at async AuthService.handleLoginUrl (file:///opt/unityhub/resources/app.asar/build/main/services/authService/AuthService.js:1:14489) {\n  response: { status: 400, statusText: 'Bad Request', data: { message: 'Input Error', code: '132.001', details: [Array] }, headers: Object [AxiosHeaders] { vary: 'Accept-Encoding', 'cache-control': 'no-cache, no-store, must-revalidate', pragma: 'no-cache', expires: '0', 'sc-request-id': 'b77f6861-20aa-4060-ac86-9f5033791fdb', 'content-type': 'application/json', via: '1.1 google', date: 'Tue, 19 Aug 2025 21:07:13 GMT', 'alt-svc': 'h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000', 'transfer-encoding': 'chunked', 'google-accounts-check-oauth-login': 'true', 'strict-transport-security': 'max-age=31536000; includeSubDomains; preload;', connection: 'close' }, request: { path: '/v1/oauth2/token', method: 'POST', host: 'api.unity.com', protocol: 'https:' } },\n  [cause]: AxiosError: Request failed with status code 400\n      at settle (file:///opt/unityhub/resources/app.asar/node_modules/axios/lib/core/settle.js:19:12)\n      at Unzip.handleStreamEnd (file:///opt/unityhub/resources/app.asar/node_modules/axios/lib/adapters/http.js:599:11)\n      at Unzip.emit (node:events:530:35)\n      at Unzip.emit (node:domain:489:12)\n      at endReadableNT (node:internal/streams/readable:1698:12)\n      at process.processTicksAndRejections (node:internal/process/task_queues:90:21) {\n    code: 'ERR_BAD_REQUEST',\n    config: { transitional: [Object], adapter: [Array], transformRequest: [Array], transformResponse: [Array], timeout: 0, xsrfCookieName: 'XSRF-TOKEN', xsrfHeaderName: 'X-XSRF-TOKEN', maxContentLength: -1, maxBodyLength: -1, env: [Object], validateStatus: [Function: validateStatus], headers: [Object [AxiosHeaders]], proxy: false, method: 'post', url: 'https://api.unity.com/v1/oauth2/token', data: 'redirect_uri=unityhub%3A%2F%2Flogin&code_verifier=TNNsjt4PZ0OeALtVNktMlFQE5sBphMTpbTTucWTstqH1glGJSGkGI3Q5wZysfacGVzJvF6cb7sgPhe9Fii4DynXYQGFdr2ahhE2k&code=ym1PR3X43MrYN5dGrph3oA002f&client_id=unity_hub&grant_type=authorization_code', allowAbsoluteUrls: true },\n    request: ClientRequest { _events: [Object: null prototype], _eventsCount: 7, _maxListeners: undefined, outputData: [], outputSize: 0, writable: true, destroyed: true, _last: true, chunkedEncoding: false, shouldKeepAlive: false, maxRequestsOnConnectionReached: false, _defaultKeepAlive: true, useChunkedEncodingByDefault: true, sendDate: false, _removedConnection: false, _removedContLen: false, _removedTE: false, strictContentLength: false, _contentLength: 232, _hasBody: true, _trailer: '', finished: true, _headerSent: true, _closed: true, _header: 'POST /v1/oauth2/token HTTP/1.1\\r\\nAccept: application/json, text/plain, */*\\r\\nContent-Type: application/x-www-form-urlencoded\\r\\nUser-Agent: axios/1.11.0\\r\\nContent-Length: 232\\r\\nAccept-Encoding: gzip, compress, deflate, br\\r\\nHost: api.unity.com\\r\\nConnection: close\\r\\n\\r\\n', _keepAliveTimeout: 0, _onPendingData: [Function: nop], agent: [BoundHttpsProxyAgent], socketPath: undefined, method: 'POST', maxHeaderSize: undefined, insecureHTTPParser: undefined, joinDuplicateHeaders: undefined, path: '/v1/oauth2/token', _ended: true, res: [IncomingMessage], aborted: false, timeoutCb: null, upgradeOrConnect: false, parser: null, maxHeadersCount: null, reusedSocket: false, host: 'api.unity.com', protocol: 'https:', _redirectable: [Writable], [Symbol(shapeMode)]: false, [Symbol(kCapture)]: false, [Symbol(kBytesWritten)]: 0, [Symbol(kNeedDrain)]: false, [Symbol(corked)]: 0, [Symbol(kChunkedBuffer)]: [], [Symbol(kChunkedLength)]: 0, [Symbol(kSocket)]: [TLSSocket], [Symbol(kOutHeaders)]: [Object: null prototype], [Symbol(errored)]: null, [Symbol(kHighWaterMark)]: 65536, [Symbol(kRejectNonStandardBodyWrites)]: false, [Symbol(kUniqueHeaders)]: null },\n    response: { status: 400, statusText: 'Bad Request', headers: [Object [AxiosHeaders]], config: [Object], request: [ClientRequest], data: [Object] },\n    status: 400\n  }\n}"}
{"timestamp":"2025-08-19T21:07:14.598Z","level":"warn","moduleName":"TokenManager","pid":37495,"message":"Encryption is not available, tokens will not be stored securely and will be discarded."}
{"timestamp":"2025-08-19T21:07:14.598Z","level":"info","moduleName":"Authentication Service","pid":37495,"message":"Fetching user info from the identity provider using access token"}
{"timestamp":"2025-08-19T21:07:14.924Z","level":"error","moduleName":"UserInfoService","pid":37495,"message":"Unable to store user info. Error: Error while encrypting the text provided to safeStorage.encryptString. Encryption is not available.\n    at UserInfoService.setUserInfoToStorage (file:///opt/unityhub/resources/app.asar/build/main/services/userInfo/userInfoService.js:1:645)\n    at AuthService.logInWithAccessToken (file:///opt/unityhub/resources/app.asar/build/main/services/authService/AuthService.js:1:8112)\n    at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n    at async AuthService.handleLoginUrl (file:///opt/unityhub/resources/app.asar/build/main/services/authService/AuthService.js:1:14585)"}
{"timestamp":"2025-08-19T21:07:14.924Z","level":"error","moduleName":"Authentication Service","pid":37495,"message":"Error fetching user info from access token: Error: Error while encrypting the text provided to safeStorage.encryptString. Encryption is not available."}
{"timestamp":"2025-08-19T21:07:14.924Z","level":"info","moduleName":"LicensingSdkService","pid":37495,"message":"checkEntitlements: checking entitlements for: com.unity.editor.ui"}
{"timestamp":"2025-08-19T21:07:14.924Z","level":"warn","moduleName":"Authentication Service","pid":37495,"message":"Could not authenticate user Error: Error while encrypting the text provided to safeStorage.encryptString. Encryption is not available.\n    at UserInfoService.setUserInfoToStorage (file:///opt/unityhub/resources/app.asar/build/main/services/userInfo/userInfoService.js:1:645)\n    at AuthService.logInWithAccessToken (file:///opt/unityhub/resources/app.asar/build/main/services/authService/AuthService.js:1:8112)\n    at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n    at async AuthService.handleLoginUrl (file:///opt/unityhub/resources/app.asar/build/main/services/authService/AuthService.js:1:14585)"}
{"timestamp":"2025-08-19T21:07:14.925Z","level":"info","moduleName":"IdentityProvider","pid":37495,"message":"First time user check: { hasEditors: true, hasProjects: false, hideGetSetUp: false, hasSeenGetSetUp: false, firstTimeUser: true }"}
{"timestamp":"2025-08-19T21:07:14.935Z","level":"info","moduleName":"LicensingSdkService","pid":37495,"message":"Successfully checked for entitlements request."}```

Hi @hughlio912_unity,

This error is caused by Electron’s safeStorage feature (which we’re adopting in Hub 3.14) failing to find a supported OS key manager. This is likely due to a known Electron bug: [Bug]: Safestorage detection fails on linux outside of predefined desktop environments · Issue #39789 · electron/electron · GitHub

As a temporary solution, we are adding a fallback to use a hardcoded plaintext password in the 3.14 GA release. This will resolve the issue, but be aware that this method is less secure.

Hey folks, the 3.14.0 general release is rolling out now. I’ve updated the post to reflect the change

The fix for your issue is included in 3.14.0. Please file a bug report if you have any further issues!

Thanks! This is working for me now, good to know about safe storage, I have an OS key manager set up so it must just not be finding it right on my linux cpu.

Hi, thank you for the update. I finally found the time to share some feedback that has been bothering me for quite a while, but I kept postponing it.

I tend to navigate quickly, and when moving the cursor up and down through the project list, the full-path tooltips keep popping up. The issue is that when moving fast, these tooltips appear in rapid succession and end up blocking mouse clicks. This makes it frustrating, sometimes I cannot open a project immediately, and on a few occasions I have even opened the wrong project because of repeated fast clicks.


These goes bigger when your projects are deeper in the folder structure.

In version 3.14.0, the longer delay helps a lot, but the tooltip still blocks interaction. A better approach would be to either let clicks pass through or make the tooltip disappear immediately when the cursor moves to a different item.

Example from 3.13

bad cpu usage for just a hub this version sends 2cpu cores in turbo just do nothing but displaying a list of projects? needs sorting out.