Elasticsearch Kibana 9.4.0 Basic authentication returns 401 Unauthorized

After upgrading from elasticsearch/kibana version 9.3.0 to elasticsearch/kibana 9.4.0 I'm no longer able to login with basic authentication via the Authorization Header.

This returns the error 401 Unauthorized.

{
"service": {
"version": "9.4.0",
"type": "kibana",
"state": "available",
"node": {
"roles": [
"background_tasks",
"ui"
]
},
"id": "X03JLrzKRxGOAfdABgkqoA"
},
"ecs": {
"version": "9.3.0"
},
"@timestamp": "2026-05-13T10:48:39.293+02:00",
"message": "Failed to activate user profile: {"error":{"root_cause":[{"type":"security_exception","reason":"unable to authenticate user [myuser_account] for action [cluster:admin/xpack/security/profile/activate]","header":{"WWW-Authenticate":["Basic realm=\"security\", charset=\"UTF-8\"","Bearer realm=\"security\"","ApiKey"]}}],"type":"security_exception","reason":"unable to authenticate user [myuser_account] for action [cluster:admin/xpack/security/profile/activate]","header":{"WWW-Authenticate":["Basic realm=\"security\", charset=\"UTF-8\"","Bearer realm=\"security\"","ApiKey"]}},"status":401}.",
"log": {
"level": "ERROR",
"logger": "plugins.security.user-profile"
},
"process": {
"pid": 121084,
"uptime": 163.995308519
},
"trace": {
"id": "bce5939754255e20e763798648dbe844"
},
"transaction": {
"id": "8fba08a59c0f9838"
}
}

{
"http": {
"response": {
"status_code": 401
},
"request": {
"method": "get",
"path": "/app/{id}/{any*}"
}
},
"error": {
"message": "security_exception\n\tRoot causes:\n\t\tsecurity_exception: unable to authenticate user [myuser_account] for action [cluster:admin/xpack/security/profile/activate]"
},
"service": {
"version": "9.4.0",
"type": "kibana",
"state": "available",
"node": {
"roles": [
"background_tasks",
"ui"
]
},
"id": "X03JLrzKRxGOAfdABgkqoA"
},
"ecs": {
"version": "9.3.0"
},
"@timestamp": "2026-05-13T10:48:39.293+02:00",
"message": "401 Unauthorized",
"log": {
"level": "ERROR",
"logger": "http"
},
"process": {
"pid": 121084,
"uptime": 163.995723184
},
"trace": {
"id": "bce5939754255e20e763798648dbe844"
},
"transaction": {
"id": "8fba08a59c0f9838"
}
}

Welcome to the forum @GeertVerbeurgt

Is this still an issue? If so, can you give a little bit more background here? You said you upgraded from 9.3.0 to 9.4.0, how precisely did you do that? Are you able to access your elasticsearch cluster at all? kibana at all? etc

Hello Kevin,

I'm using the ELK stack on a Linux environment. For that I dowload and extract the installation files.
For version 9.4.0 I used 'elasticsearch-9.4.0-linux-x86_64.tar.gz' and 'kibana-9.4.0-linux-x86_64.tar.gz' for the installation.
The data is located in a separate folder and is automatically used by the recently installed version.
Everything works correctly in Elasticsearch and Kibana, except for basic authentication.

To login to Kibana, we use Apache configuration with an Authorization header via Basic Authentication ( needed for security reason ).

RequestHeader set Authorization "expr=Basic {base64-encoded string}"
ProxyPass ``https://127.0.0.1:8100/
ProxyPassReverse ``https://127.0.0.1:8100/

We have been using this proxy configuration since version 8 of the ELK stack, and it has worked without problems with every upgrade up until now. According to the documentation, this is still supported :/docs/deploy-manage/users-roles/cluster-or-deployment-auth/kibana-authentication#basic-authentication

Thank you in advance for taking a look at this.

Mmm, I am not really looking at it per se. Your explanation of issue in this followup is much clearer, thanks for that as it will likely help others. Might also be useful to share elasticsearch.yml and kibana.yml. I note that you are using non-standard ports and apache as proxy, so it's not quite a OOTB config.

As written, at face value, would seem like a bug. However, to be sure, you wrote:

Can you confirm that authentication to elasticsearch works, e.g. with curl? Something like:

curl -vk   -H  'Authorization: Basic xxxxx'   https://127.0.0.1:8100/

e.g. for my install the following "works" in that it gets a 200, and I'm using 9.4.0 too.

curl -vk -H 'Authorization: Basic xxxxx'  "https://${KIBHOST}:${KIBPORT}/app/id/any*"

where my xxxxx is generated by

echo -n "user:pass"| base64

EDIT: I see I wrote "confirm that authentication to elasticsearch works", but the URL was to kibana (presumably listening on port 8100 in your case). Now its arguably semantics if thats elasticsearch authentication or kibana authentication , but in any case, on assumption the user has appropriate permissions, following should also give 200,

curl -vk -H 'Authorization: Basic xxxxx'  "https://${ESHOST}:${ESPORT}/"

and this isn't an apache forum, but is

RequestHeader set Authorization "expr=Basic {base64-encoded string}"

not better replaced by

RequestHeader set Authorization "Basic {base64-encoded string}"

Authentication to elasticsearch with curl and Authorization header -> OK
curl -vk -H 'Authorization: Basic xxxxx' "``https://$``{elasticsearch host}:9200/_security/user"

Authentication via the login page of Kibana -> OK

Authentication to kibana with curl and Authorization header -> NOK - HTTP return code 401 Unauthorized

curl -vk -H 'Authorization: Basic {base64-encoded string}'  "https://127.0.0.1:8100/app/id/any*

Trying 127.0.0.1...
TCP_NODELAY set
Connected to 127.0.0.1 (127.0.0.1) port 8100 (#0)
ALPN, offering h2
ALPN, offering http/1.1
successfully set certificate verify locations:
CAfile: /etc/pki/tls/certs/ca-bundle.crt
CApath: none
TLSv1.3 (OUT), TLS handshake, Client hello (1):
TLSv1.3 (IN), TLS handshake, Server hello (2):
TLSv1.3 (IN), TLS handshake, [no content] (0):
TLSv1.3 (IN), TLS handshake, Encrypted Extensions (8):
TLSv1.3 (IN), TLS handshake, [no content] (0):
TLSv1.3 (IN), TLS handshake, Certificate (11):
TLSv1.3 (IN), TLS handshake, [no content] (0):
TLSv1.3 (IN), TLS handshake, CERT verify (15):
TLSv1.3 (IN), TLS handshake, [no content] (0):
TLSv1.3 (IN), TLS handshake, Finished (20):
TLSv1.3 (OUT), TLS change cipher, Change cipher spec (1):
TLSv1.3 (OUT), TLS handshake, [no content] (0):
TLSv1.3 (OUT), TLS handshake, Finished (20):
SSL connection using TLSv1.3 / TLS_AES_256_GCM_SHA384
ALPN, server accepted to use h2
Server certificate:
subject: CN={common name}
start date: Apr  7 08:07:14 2026 GMT
expire date: Apr  7 08:07:14 2027 GMT
issuer: CN={common name}
SSL certificate verify ok.
Using HTTP2, server supports multi-use
Connection state changed (HTTP/2 confirmed)
Copying HTTP/2 data in stream buffer to connection buffer after upgrade: len=0
TLSv1.3 (OUT), TLS app data, [no content] (0):
TLSv1.3 (OUT), TLS app data, [no content] (0):
TLSv1.3 (OUT), TLS app data, [no content] (0):
Using Stream ID: 1 (easy handle 0x5607350046f0)
TLSv1.3 (OUT), TLS app data, [no content] (0):
GET /app/id/any* HTTP/2
Host: 127.0.0.1:8100
User-Agent: curl/7.61.1
Accept: /
Authorization: Basic {base64-encoded string}
TLSv1.3 (IN), TLS handshake, [no content] (0):
TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
TLSv1.3 (IN), TLS handshake, [no content] (0):
TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
TLSv1.3 (IN), TLS app data, [no content] (0):
Connection state changed (MAX_CONCURRENT_STREAMS == 4294967295)!
TLSv1.3 (OUT), TLS app data, [no content] (0):
TLSv1.3 (IN), TLS app data, [no content] (0):
TLSv1.3 (IN), TLS app data, [no content] (0):
< HTTP/2 401
< www-authenticate: Basic realm="security", charset="UTF-8", Bearer realm="security", ApiKey
< x-content-type-options: nosniff
< referrer-policy: strict-origin-when-cross-origin
< permissions-policy: camera=(), display-capture=(), fullscreen=(self), geolocation=(), microphone=(), web-share=()
< cross-origin-opener-policy: same-origin
< content-security-policy: script-src 'report-sample' 'self'; worker-src 'report-sample' 'self' blob:; style-src 'report-sample' 'self' 'unsafe-inline'; object-src 'report-sample' 'none'
< content-security-policy-report-only: form-action 'report-sample' 'self'; default-src 'report-sample' 'none'; font-src 'report-sample' 'self'; img-src 'report-sample' 'self' data: tiles.maps.elastic.co; connect-src 'report-sample' 'self' telemetry.elastic.co telemetry-staging.elastic.co feeds.elastic.co tiles.maps.elastic.co vector.maps.elastic.co; script-src 'report-sample' 'self'; worker-src 'report-sample' 'self' blob:; style-src 'report-sample' 'self' 'unsafe-inline'; object-src 'report-sample' 'none'
< kbn-name: {hostname}
< kbn-license-sig: {license-sig}
< refresh: 0;url=/login?msg=UNAUTHENTICATED&next=%2Fapp%2Fid%2Fany*
< content-type: text/html; charset=utf-8
< cache-control: private, no-cache, no-store, must-revalidate
< content-length: 891
< date: Mon, 18 May 2026 13:10:50 GMT
<

Kibana.yml

pid.file: "kibana.pid"

logging.appenders.default:
  type: rolling-file
  fileName: "kibana.log"
  policy:
    type: time-interval
    interval: 24h
  strategy:
    type: numeric
    max: 10
  layout:
    type: json

logging.loggers:
  - name: elasticsearch.query
    level: error

#ssl configuration
server.port: 8100
server.host: "127.0.0.1"
server.ssl.enabled: true
server.publicBaseUrl: {public base url}
server.ssl.keystore.path: server.p12

elasticsearch.hosts: "https://{elasticsearch hostname}:9200"
elasticsearch.username: {username}
elasticsearch.ssl.keystore.path: http_server.p12
elasticsearch.ssl.truststore.path: truststore.p12
elasticsearch.ssl.alwaysPresentCertificate: true
elasticsearch.ssl.verificationMode: full

#encryption keys
xpack.encryptedSavedObjects.encryptionKey: {encryptionKey}
xpack.reporting.encryptionKey: {encryptionKey}
xpack.security.encryptionKey: {encryptionKey}

Elasticsearch.yml

discovery.seed_hosts: [{host1},{host2},{host3}]
path.repo: [{path to repo}]
path.data: {path to data}
path.logs: {path to logs}
network.host: {network host}
cluster.name: {elasticsearch.clustername}
node.name: {node name}
indices.memory.index_buffer_size: 50%
indices.breaker.total.use_real_memory: false
http.port: 9200
transport.port: 9300

#ssl configuration
xpack.security.enabled: true
xpack.security.transport.ssl.enabled: true
xpack.security.transport.ssl.verification_mode: full
xpack.security.transport.ssl.keystore.path: cert/transport_server.p12
xpack.security.transport.ssl.truststore.path: cert/transport_truststore.p12
xpack.security.http.ssl.enabled: true
xpack.security.http.ssl.keystore.path: cert/http_server.p12
xpack.security.http.ssl.truststore.path: cert/http_truststore.p12
xpack.security.http.ssl.truststore.type: PKCS12
xpack.security.http.ssl.client_authentication: required

Can you please try curl with the -H "Authorization: Basic ..." header to https://127.0.0.1:8100/api/status endpoint, and tell me if its still a 401 please?

curl -vk -H 'Authorization: Basic {basic64-encoded string}' "``https://127.0.0.1:8100/api/status``" -> OK

< HTTP/2 200
< elastic-api-version: 2023-10-31
< x-content-type-options: nosniff
< referrer-policy: strict-origin-when-cross-origin
< permissions-policy: camera=(), display-capture=(), fullscreen=(self), geolocation=(), microphone=(), web-share=()
< cross-origin-opener-policy: same-origin
< content-security-policy: script-src 'report-sample' 'self'; worker-src 'report-sample' 'self' blob:; style-src 'report-sample' 'self' 'unsafe-inline'; object-src 'report-sample' 'none'
< content-security-policy-report-only: form-action 'report-sample' 'self'; default-src 'report-sample' 'none'; font-src 'report-sample' 'self'; img-src 'report-sample' 'self' data: ``tiles.maps.elastic.co``; connect-src 'report-sample' 'self' ``telemetry.elastic.co`` ``telemetry-staging.elastic.co`` ``feeds.elastic.co`` ``tiles.maps.elastic.co`` ``vector.maps.elastic.co``; script-src 'report-sample' 'self'; worker-src 'report-sample' 'self' blob:; style-src 'report-sample' 'self' 'unsafe-inline'; object-src 'report-sample' 'none'

I forgot the /api/status URL needs no auth at all, so that tells us little. /api/features would tell a little more.

But I think you/we need a kibana auth expert to weigh in, I think you've shared enough to give some clues here. I note the 401 includes

< refresh: 0;url=/login?msg=UNAUTHENTICATED&next=%2Fapp%2Fid%2Fany*

and maybe something changed with what the HTTP Basic auth can access OOTB on 9.4.0 vs 9.3.0. Or something entirely different.

curl -sk -H 'Authorization: Basic xxxxx' "https://${ESHOST}:${ESPORT}/_security/user/_privileges"

might tell you a little more too!? Good luck.

Hi @GeertVerbeurgt Welcome to the community...

Nope it works :slight_smile: I just validated BUT I did think it did not work at first... simple error...

My suspicion you are generating the the base64 wrong

Example on a mac

Incorrect

$echo 'elastic:mypassword' | base64 
ZWxhc3RpYzpteXBhc3N3b3JkCg==

curl -k -H "Authorization: Basic ZWxhc3RpYzpteXBhc3N3b3JkCg==" https://localhost:9200
{"error":{"root_cause":[{"type":"security_exception","reason":"unable to authenticate user [elastic] for REST request [/]","header":{"WWW-Authenticate":["Basic realm=\"security\", charset=\"UTF-8\"","Bearer realm=\"security\"","ApiKey"]}}],"type":"security_exception","reason":"unable to authenticate user [elastic] for REST request [/]","header":{"WWW-Authenticate":["Basic realm=\"security\", charset=\"UTF-8\"","Bearer realm=\"security\"","ApiKey"]}},"status":401}

Correct: Note the -n no newline :slight_smile: so it does not encode the newline = bad password

$ echo -n 'elastic:mypassword' | base64                                            
ZWxhc3RpYzpteXBhc3N3b3Jk

curl -k -H "Authorization: Basic ZWxhc3RpYzpteXBhc3N3b3Jk" https://localhost:9200 
{
  "name" : "es01",
  "cluster_name" : "docker-cluster",
  "cluster_uuid" : "qAFMoDDYTWKTH5w0WvEN1w",
  "version" : {
    "number" : "9.4.1",
    "build_flavor" : "default",
    "build_type" : "docker",
    "build_hash" : "3c7c6027c5769d860d87448e2749f4c550a239da",
    "build_date" : "2026-05-08T10:08:29.383338563Z",
    "build_snapshot" : false,
    "lucene_version" : "10.4.0",
    "minimum_wire_compatibility_version" : "8.19.0",
    "minimum_index_compatibility_version" : "8.0.0"
  },
  "tagline" : "You Know, for Search"
}

Hello @stephenb,

According to your URL, you are establishing a basic authentication connection with Elasticsearch (port 9200). That is not the problem and works (see conversation history). It is the basic authentication with Kibana (port 8100) that does not work.

Kr,

Geert

Apologies the Title of the Thread Says Elasticsearch

My Kibana runs on 5601 the default port.
It works as well (it is running on http)

$ curl -k -H "Authorization: Basic ZWxhc3RpYzpteXBhc3N3b3Jk" http://localhost:5601/api/spaces/space | jq      
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100   136  100   136    0     0   8362      0 --:--:-- --:--:-- --:--:--  8500
[
  {
    "id": "default",
    "name": "Default",
    "description": "This is your default space!",
    "color": "#00bfb3",
    "disabledFeatures": [],
    "_reserved": true
  }
]

Perhaps I am missing something...

Are you trying to Access APM server or Fleet Server?

I see you set kibana to 8100 not sure why

What is this set to?

server.publicBaseUrl: {public base url}

Pretty sure if Basic Auth was broke for Kibana APIs I would think we would be getting lots of reports... perhaps there is an issue but I am not seeing it

I ran this against are fully secured 9.4.1.

 curl -H "Authorization: Basic 12341234ncmVlbmdlY2tvMTIzIQ==" https://kb.mydomain.net:5601/api/spaces/space | jq
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100   416  100   416    0     0  14633      0 --:--:-- --:--:-- --:--:-- 14857
[
  {
    "id": "default",
    "name": "Default",
    "description": "This is your default space!",
    "color": "#00bfb3",
    "initials": "D",
    "imageUrl": "",
    "disabledFeatures": [
      "siemV5",
      "securitySolutionCasesV3",
      "securitySolutionAssistant",
      "securitySolutionAttackDiscovery",
      "securitySolutionTimeline",
      "securitySolutionNotes",
      "securitySolutionRulesV4",
      "securitySolutionAlertsV1",
      "securitySolutionSiemMigrations"
    ],
    "_reserved": true,
    "solution": "oblt"
  }
]

If I mess up the Basic Authi I get

$ curl -H "Authorization: Basic 12341234YzpncmVlbmdlY2tvMTssIzIQ==" https://kb.mydomain.net:5601/api/spaces/space | jq
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100   299  100   299    0     0  10541      0 --:--:-- --:--:-- --:--:-- 10678
{
  "statusCode": 401,
  "error": "Unauthorized",
  "message": "[security_exception\n\tCaused by:\n\t\tillegal_argument_exception: Input byte array has wrong 4-byte ending unit\n\tRoot causes:\n\t\tsecurity_exception: invalid basic authentication header encoding]: invalid basic authentication header encoding"
}

At this point I can not reproduce... perhaps I am still missing something

Is it possible the the user you are using does not have Kibana Priviliges?

To be Precise Both of these are 9.4.1

I can test on 9.4.0 tomorrow if needed.

Here is what my API status looks like .....

curl -H "Authorization: Basic 21341234VlbmdlY2tvMTIzIQ==" https://kb.mydomain.net:5601/api/status 

{
  "name": "c9ee726f0ce4",
  "uuid": "f07f8027-849e-403c-b9e7-4282eeabae7e",
  "version": {
    "number": "9.4.1",
    "build_hash": "6b92ccb460a725bd951d72bba6ead7b9697f9c6b",
    "build_number": 101712,
    "build_snapshot": false,
    "build_flavor": "traditional",
    "build_date": "2026-05-08T15:56:48.491Z"
  },
  "status": {
    "overall": {
      "level": "available",
      "summary": "All services and plugins are available"
    },
    "core": {
      "elasticsearch": {
        "level": "available",
        "summary": "Elasticsearch is available",
        "meta": {
....
 "plugins": {
      "alerting": {
        "level": "available",
        "summary": "Alerting is (probably) ready",
        "reported": true
      },
      "triggersActionsUi": {
        "level": "available",
        "summary": "All services and plugins are available"
      },
      "transform": {
        "level": "available",
        "summary": "All services and plugins are available"
      },
...

I think if we go full circle you have bad permissions on this user

Looked at our KB

If this started suddenly

Common reasons are:

  • password changed
  • token expired
  • user disabled/locked
  • realm/provider config changed
  • Kibana or proxy started stripping/modifying auth headers

Yesterday I installed version 9.4.1 and still got the problem.

server.publicBaseUrl

Supported on: Self-managed

The publicly available URL that end-users access Kibana at. Must include the protocol, hostname, port (if different than the defaults for http and https, 80 and 443 respectively), and the server.basePath (when that setting is configured explicitly). This setting cannot end in a slash (/).

Datatype: string

With the URL '/api/spaces/space', I also have an HTTP 200 response.

curl -vk -H 'Authorization: Basic {base64-encoded string}'  "http://127.0.0.1:8100/api/spaces/space"

Trying 127.0.0.1...

TCP_NODELAY set

Connected to 127.0.0.1 (127.0.0.1) port 8100 (#0)

GET /api/spaces/space HTTP/1.1
Host: 127.0.0.1:8100
User-Agent: curl/7.61.1
Accept: /
Authorization: Basic {base64-encoded string}

< HTTP/1.1 200 OK
< elastic-api-version: 2023-10-31
< x-content-type-options: nosniff
< referrer-policy: strict-origin-when-cross-origin
< permissions-policy: camera=(), display-capture=(), fullscreen=(self), geolocation=(), microphone=(), web-share=()
< cross-origin-opener-policy: same-origin
< content-security-policy: script-src 'report-sample' 'self'; worker-src 'report-sample' 'self' blob:; style-src 'report-sample' 'self' 'unsafe-inline'; object-src 'report-sample' 'none'
< content-security-policy-report-only: form-action 'report-sample' 'self'; default-src 'report-sample' 'none'; font-src 'report-sample' 'self'; img-src 'report-sample' 'self' data: tiles.maps.elastic.co; connect-src 'report-sample' 'self' telemetry.elastic.co telemetry-staging.elastic.co feeds.elastic.co tiles.maps.elastic.co vector.maps.elastic.co; script-src 'report-sample' 'self'; worker-src 'report-sample' 'self' blob:; style-src 'report-sample' 'self' 'unsafe-inline'; object-src 'report-sample' 'none'
< kbn-name: {hostname}
< kbn-license-sig: {kbn-license-sig}
< content-type: application/json; charset=utf-8
< cache-control: private, no-cache, no-store, must-revalidate
< content-length: 136
< accept-ranges: bytes
< Date: Tue, 19 May 2026 06:15:03 GMT
< Connection: keep-alive
< Keep-Alive: timeout=120
<

Connection #0 to host 127.0.0.1 left intact
[{"id":"default","name":"Default","description":"This is your default space!","color":"#00bfb3","disabledFeatures":
,"_reserved":true}]

The URL '/app/id/any*' returns http 401 Unauthorized.

Authentication via the Kibana login page with the user is no problem. So the privileges are ok and the user is already used since version 8.

API Status

"uuid": "23b79d0c-f8e3-46ab-b9e3-10272371808a",
"version": {
	"number": "9.4.1",
	"build_hash": "6b92ccb460a725bd951d72bba6ead7b9697f9c6b",
	"build_number": 101712,
	"build_snapshot": false,
	"build_flavor": "traditional",
	"build_date": "2026-05-08T15:56:48.491Z"
},
"status": {
	"overall": {
		"level": "available",
		"summary": "All services and plugins are available"
	},
	"core": {
		"elasticsearch": {
			"level": "available",
			"summary": "Elasticsearch is available",
			"meta": {
				"warningNodes": [],
				"incompatibleNodes": []
			}
		},
		"savedObjects": {
			"level": "available",
			"summary": "SavedObjects service has completed migrations and is available",
			"meta": {
				"migratedIndices": {
					"migrated": 0,
					"skipped": 0,
					"patched": 8
				}
			}
		}
	},
	"plugins": {
		"alerting": {
			"level": "available",
			"summary": "Alerting is (probably) ready",
			"reported": true
		},
		"triggersActionsUi": {
			"level": "available",
			"summary": "All services and plugins are available"
		},
		"transform": {
			"level": "available",
			"summary": "All services and plugins are available"
		},
		"stackConnectors": {
			"level": "available",
			"summary": "All services and plugins are available"
		},
		"workflowsManagement": {
			"level": "available",
			"summary": "All services and plugins are available"
		},
		"agentBuilder": {
			"level": "available",
			"summary": "All services and plugins are available"
		},
        ....
        For all plugins "All services and plugins are available"

Kibana UI login is Kibana UI login. Your users privileges are fine to interactively login to the kibana UI. But accessing kibana paths like /app/id/any* is perhaps controlled differently , and in fact you are specifically referred to /login in the 401. Would be interesting to see what specific set of roles are defined for your user, either in the UI or via API.

The test users I created/tested on 9.4.0 with different combinations of roles could either access both the kibana UI and the /app/.. paths, or neither. You (@GeertVerbeurgt) seem to have a user that can access the UI but not access the /app/... paths with the equivalent 'Authorization: Basic xxxxx' header, correct? But I could not find such a magic combination, albeit not with a massive effort to do so.

Also, you noted it worked OK in 9.3.0. Can you reduce things to a simple but reproducible case, where anyone could download the tarballs/rpms/debs of 9.3.0 and 9.4.0 and on a pair of completely fresh OOTB systems, and following your specific set of steps, then see "this works" on 9.3.0 and "this does not work the same" on 9.4.0? ie. a regression ?

The user i use has the 'superuser' role.

I will try to setup an fresh environment for 9.3.0 and 9.4.0 and see what happens

To be honest, I will be pretty surprised if you can reproduce, because I've done precisely that test myself already, with 9.4.0, and I cannot generate a 401 with a user with superuser role who has right credentials to login to Kibana UI and the right base64 string in the header to curl.

btw, you were asked what value you had set server.publicBaseUrl to, if any. I don't think you answered? So in my tests I just left it unset.

I guess there might be some additional debug or trace-level logging enable-able in kibana that might also help, but sadly I dont know which specific setting might help.

btw, I also noticed in earlier output:

But in most recent output

Note one was a http URL, and protocol selected was http/1.1. The older other was a https URL, and selected http/2.

Did you disable SSL to ease troubleshooting ?

For server.publicBaseUrl I posted an answer in a previous post. In fact it's the publicly available URL that end-users access Kibana at. This is of no importance to this issue.

I disabled once ssl to see if I had a different behaviour. Both for http and https I had the same issue.

I'm now busy setting up the 2 environments.

Hi @GeertVerbeurgt

I thought that was an example not the literal URL you were trying

Although it is unclear what the purpose of this is to me
I tried that exact URL and it returned fine, no 401

This is 9.4.1 Fully Secured Cluster

curl -H "Authorization: Basic dsfgsdfgdsfgncmVlbmdlY2tvMTIzIQ==" "https://kb.mydomain.net:5601/app/id/any*" 

Returned a bunch of HTML that started like this
No Auth Error

<!DOCTYPE html><html lang="en"><head><meta charSet="utf-8"/><meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"/><meta name="viewport" content="width=device-width"/><title>Elastic</title><style>
        
        @font-face {
          font-family: 'Elastic UI Numeric';
          font-style: normal;
          font-weight: 100 900;
          font-display: swap;
          src: url('/6b92ccb460a7/ui/fonts/elastic_ui_numeric/ElasticUINumeric-Variable.woff2') format('woff2');
          unicode-range: U+20, U+24-25, U+28-29, U+2B-2F, U+30-3A, U+A0, U+202F, U+2212;
        }

        @font-face {
          font-family: 'Inter';
          font-style: normal;
          font-weight: 100;
          src: url('/6b92ccb460a7/ui/fonts/inter/Inter-Thin.woff2') format('woff2');
        }

        @font-face {
          font-family: 'Inter';
          font-style: italic;
          font-weight: 100;
          src: url('/6b92ccb460a7/ui/fonts/inter/Inter-ThinItalic.woff2') format('woff2');
        }

        @font-face {
          font-family: 'Inter';
          font-style: normal;
          font-weight: 200;
          src: url('/6b92ccb460a7/ui/fonts/inter/Inter-ExtraLight.woff2') format('woff2');
        }

        @font-face {
          font-family: 'Inter';
          font-style: italic;
          font-weight: 200;
          src: url('/6b92ccb460a7/ui/fonts/inter/Inter-ExtraLightItalic.woff2') format('woff2');
        }

Let us know what you find out...

I am showing these because it is importat to be able to reproduce ... at this point I can not ...

That STILL does not mean there is not an issue but does tend to point to a specific configuration.

Debug as @RainTown suggests below is probably the next step.