HA docker - recorder giving access denied connecting to mariadb

I’ve HA (v2025-12-4) installed in Docker using ‘docker compose’ on Truenas Scale (v25.10.1) together with adminer, influxdb (v2.8.0) and mariadb (v12.1.2), each in their own docker container.
When HA starts and tries to configure the recorder, I can see access denied entries in the mariadb log and the recorder fails to load.

I can connect to the ‘homeassistant’ database using the set user ‘homeassistant_sql’ and respective password through ‘adminer’ OK, and that SQL account has full rights on the database.

Any idea why HA cannot connect to the db, while I can connect OK to it through adminer?

2026-01-11 19:01:24 27 [Warning] Access denied for user 'homeassistant_sql'@'172.16.7.6' (using password: YES)
2026-01-11 19:01:27 28 [Warning] Access denied for user 'homeassistant_sql'@'172.16.7.6' (using password: YES)
2026-01-11 19:01:30 29 [Warning] Access denied for user 'homeassistant_sql'@'172.16.7.6' (using password: YES)
  • The 3 docker containers use the same docker network named ‘ha_network’
  • ha and the other docker containers are behind a Traefik reverse proxy. I can access ha ok via its domain name.
  • named the mariadb container ‘ha-mariadb’
  • mariadb section in ha configuration.yaml:
# MariaDB integration
recorder:
  db_url: !secret recorder_db_url
  purge_keep_days: 366
  auto_purge: true
  commit_interval: 60
  • recorder_db_url in secrets.yaml
    recorder_db_url: ‘mysql://homeassistant_sql:5ruralfreedelivery^:@ha-mariadb:3306/homeassistant?charset=utf8mb4’

All this knowledge, and no log-files to interpret, not even debug ?
Can you ssh to the DB from HA ?

Just Curious, is these “signs” last 2, really needed in your passwd ?

Sorry for not attaching log files, not sure how to attach log files here though…

  • I did add a ‘test1’ user to the ‘homeassistant’ db with password ‘test2’ and full rights on the db. → same issue

I do have debug enabled on the ha logs, will try to get the relevant sections out.
(there are quite a few other (knx) errors which I still have to clean up)

  • As far as I can tell, port 3306 is only available on the docker network ‘ha_network’ and is not exposed on the host. I’ll try using just 1 docker network ‘proxy_network’ which I use mainly to talk to the reverse proxy or expose ports on the host.

mariaddb logs:

2026-01-12 00:53:12+00:00 [Note] [Entrypoint]: Entrypoint script for MariaDB Server 1:12.1.2+maria~ubu2404 started.
2026-01-12 00:53:12+00:00 [Warn] [Entrypoint]: /sys/fs/cgroup///memory.pressure not writable, functionality unavailable to MariaDB
2026-01-12 00:53:12+00:00 [Note] [Entrypoint]: Switching to dedicated user 'mysql'
2026-01-12 00:53:12+00:00 [Note] [Entrypoint]: Entrypoint script for MariaDB Server 1:12.1.2+maria~ubu2404 started.
2026-01-12 00:53:12+00:00 [Note] [Entrypoint]: MariaDB upgrade not required
2026-01-12  0:53:12 0 [Note] Starting MariaDB 12.1.2-MariaDB-ubu2404 source revision 70117463f032d59f8e328335e19b59157d34cf07 server_uid waUXkXhvyQSLodN4MoefaZbhWPY= as process 1
2026-01-12  0:53:13 0 [Note] InnoDB: Compressed tables use zlib 1.3
2026-01-12  0:53:13 0 [Note] InnoDB: Number of transaction pools: 1
2026-01-12  0:53:13 0 [Note] InnoDB: Using crc32 + pclmulqdq instructions
2026-01-12  0:53:13 0 [Note] InnoDB: Using io_uring
2026-01-12  0:53:13 0 [Note] InnoDB: innodb_buffer_pool_size_max=128m, innodb_buffer_pool_size=128m
2026-01-12  0:53:13 0 [Note] InnoDB: Completed initialization of buffer pool
2026-01-12  0:53:13 0 [Note] InnoDB: Buffered log writes (block size=512 bytes)
2026-01-12  0:53:13 0 [Note] InnoDB: End of log at LSN=223442398226
2026-01-12  0:53:13 0 [Note] InnoDB: Opened 3 undo tablespaces
2026-01-12  0:53:13 0 [Note] InnoDB: 128 rollback segments in 3 undo tablespaces are active.
2026-01-12  0:53:13 0 [Note] InnoDB: Setting file './ibtmp1' size to 12.000MiB. Physically writing the file full; Please wait ...
2026-01-12  0:53:13 0 [Note] InnoDB: File './ibtmp1' size is now 12.000MiB.
2026-01-12  0:53:13 0 [Note] InnoDB: log sequence number 223442398226; transaction id 3339609
2026-01-12  0:53:13 0 [Note] Plugin 'FEEDBACK' is disabled.
2026-01-12  0:53:13 0 [Note] Plugin 'wsrep-provider' is disabled.
2026-01-12  0:53:13 0 [Note] InnoDB: Loading buffer pool(s) from /var/lib/mysql/ib_buffer_pool
2026-01-12  0:53:13 0 [Note] InnoDB: Buffer pool(s) load completed at 260112  0:53:13
2026-01-12  0:53:15 0 [Note] Server socket created on IP: '0.0.0.0', port: '3306'.
2026-01-12  0:53:15 0 [Note] Server socket created on IP: '::', port: '3306'.
2026-01-12  0:53:15 0 [Note] mariadbd: Event Scheduler: Loaded 0 events
2026-01-12  0:53:15 0 [Note] mariadbd: ready for connections.
Version: '12.1.2-MariaDB-ubu2404'  socket: '/run/mysqld/mysqld.sock'  port: 3306  mariadb.org binary distribution
2026-01-12  0:53:22 3 [Warning] Access denied for user 'test1'@'172.16.7.6' (using password: YES)
2026-01-12  0:53:25 4 [Warning] Access denied for user 'test1'@'172.16.7.6' (using password: YES)
2026-01-12  0:53:28 5 [Warning] Access denied for user 'test1'@'172.16.7.6' (using password: YES)
2026-01-12  0:53:31 6 [Warning] Access denied for user 'test1'@'172.16.7.6' (using password: YES)
2026-01-12  0:53:34 7 [Warning] Access denied for user 'test1'@'172.16.7.6' (using password: YES)
2026-01-12  0:53:37 8 [Warning] Access denied for user 'test1'@'172.16.7.6' (using password: YES)
2026-01-12  0:53:41 9 [Warning] Access denied for user 'test1'@'172.16.7.6' (using password: YES)
2026-01-12  0:53:44 10 [Warning] Access denied for user 'test1'@'172.16.7.6' (using password: YES)
2026-01-12  0:53:47 11 [Warning] Access denied for user 'test1'@'172.16.7.6' (using password: YES)
2026-01-12  0:53:50 12 [Warning] Access denied for user 'test1'@'172.16.7.6' (using password: YES)

docker-compose file:

# homeassistant
    # ghcr.io/home-assistant/home-assistant:stable # -> GitHub source
    # homeassistant/home-assistant:2022.11.1 # -> docker hub source
    # https://github.com/home-assistant/core/releases 

services:
  homeassistant:
    image: ghcr.io/home-assistant/home-assistant:2025.12.4  #2025.11.3 
    container_name: "homeassistant"
    restart: unless-stopped
    ports:
      #- "192.168.0.151:8123:8123"
      #- "12443:8443"
      - "192.168.0.151:51827:51827"
      - "192.168.0.151:5353:5353"
      - "192.168.0.151:3671:3671"
    volumes:
      - ha_config:/config
      - /etc/localtime:/etc/localtime:ro
      - certs:/certs:ro
      - /run/dbus:/run/dbus:ro
    networks:
      - proxy_network
      - ha-macvlan_network
      - ha_network
    labels:
      - "traefik.enable=true"
      - "traefik.docker.network=proxy_network"
      - "traefik.http.routers.homeassistant-secure.entrypoints=websecure"
      - "traefik.http.routers.homeassistant-secure.rule=Host(`ha.nexusnet.me`)"
      - "traefik.http.routers.homeassistant-secure.tls=true"
      - "traefik.http.routers.homeassistant-secure.service=homeassistant"
      - "traefik.http.services.homeassistant.loadbalancer.server.port=8123"
      - "traefik.http.services.homeassistant.loadbalancer.server.scheme=https"
      # Whats Up Docker
      - 'wud.watch=true'
      - 'wud.tag.include=^\d+\.\d+\.\d+$$'
    environment:
      - TZ=Europe/Dublin
    depends_on:
      - mariadb
      - influxdb
    deploy:
      mode: replicated
      replicas: 1
      resources:
        limits:
          cpus: 8
          memory: 2G
 
# influxDB
# https://github.com/influxdata/influxdb/releases
  influxdb:
    image: influxdb:2.8.0 #2.7.12 # 2.7.11 #2.7.8
    container_name: "ha-influxdb"
    restart: unless-stopped
    networks:
      #- proxy_network
      - ha_network
    #ports:
    #  - "8086:8086"
    #  - "8083:8083"
    environment:
      DOCKER_INFLUXDB_INIT_MODE: setup
      DOCKER_INFLUXDB_INIT_USERNAME_FILE: /run/secrets/influxdb2_ha-user
      DOCKER_INFLUXDB_INIT_PASSWORD_FILE: /run/secrets/influxdb2_ha-user-password
      DOCKER_INFLUXDB_INIT_ORG: 'Andromeda'
      DOCKER_INFLUXDB_INIT_BUCKET: 'homeassistant'
      DOCKER_INFLUXDB_INIT_ADMIN_TOKEN_FILE: /run/secrets/influxdb2_admin-token
    secrets:
      - influxdb2_ha-user
      - influxdb2_ha-user-password
      - influxdb2_admin-token
    volumes:
      - influxdb_data:/var/lib/influxdbv2:rw
      - influxdb_config:/etc/influxdbv2:rw
      - /etc/localtime:/etc/localtime:ro
    labels:
      # Whats Up Docker
      - 'wud.watch=true'
      - 'wud.tag.include=^\d+\.\d+\.\d+$$'
    deploy:
      mode: replicated
      replicas: 1
      resources:
        limits:
          cpus: 8
          memory: 2G

# grafana
# https://github.com/grafana/grafana
  grafana:
    depends_on:
      - influxdb
    image: grafana/grafana:12.3.1 #11.1.1 #10.4.2 # 10.3.3 # 10.0.0
    container_name: "ha-grafana"
    restart: unless-stopped
    networks:
      - proxy_network
      - ha_network
    #ports:
    #  - "192.168.0.151:3000:3000"
    user: 500:500
    environment:
      - GF_INSTALL_PLUGINS=grafana-clock-panel,briangann-gauge-panel,natel-plotly-panel,grafana-simple-json-datasource
    volumes:
      #- grafana_config/custom.ini:/etc/grafana/grafana.ini
      - grafana_config:/etc/grafana
      - grafana_data:/var/lib/grafana
      - /etc/localtime:/etc/localtime:ro
    labels:
      - "traefik.enable=true"
      #- "traefik.docker.network=proxy_network"
      - "traefik.http.routers.homeassistant-grafana-secure.entrypoints=websecure"
      - "traefik.http.routers.homeassistant-grafana-secure.rule=Host(`ha-grafana.nexusnet.me`)"
      - "traefik.http.routers.homeassistant-grafana-secure.tls=true"
      - "traefik.http.routers.homeassistant-grafana-secure.service=homeassistant-grafana"
      - "traefik.http.services.homeassistant-grafana.loadbalancer.server.port=3000"
      - "traefik.http.services.homeassistant-grafana.loadbalancer.server.scheme=http"

    # Whats Up Docker
      - 'wud.watch=true'
      - 'wud.tag.include=^\d+\.\d+\.\d+$$'
    deploy:
      mode: replicated
      replicas: 1
      resources:
        limits:
          cpus: 4
          memory: 256M 

# mariadb / SQL database
# https://github.com/MariaDB/server
  mariadb:
    image: mariadb:12.1.2 #11.4.2 #11.3.2 # 10.11.3
    container_name: "ha-mariadb"
    restart: unless-stopped
    security_opt:
      - "seccomp=unconfined"
     
    #ports:
    #  - "192.168.0.151:3306:3306"
    #user: 1000:1000
    environment:
      - MYSQL_USER_FILE=/run/secrets/ha_mariadb_user
      - MYSQL_DATABASE=homeassistant
      - MYSQL_PASSWORD_FILE=/run/secrets/ha_mariadb_user-password
      - MYSQL_ROOT_PASSWORD_FILE=/run/secrets/ha_mariadb_root-password
      - log_warnings=3  # 1 errors only || 2 errors and warnings || 3 errors warnings notes --> default is 3
      #- MYSQL_HOST=ha-mariadb
      #- MARIADB_AUTO_UPGRADE=1
    secrets:
      - ha_mariadb_user
      - ha_mariadb_user-password
      - ha_mariadb_root-password
    volumes:
      - mariadb_data:/var/lib/mysql
      #- mariadb_config/my.cnf:/etc/mysql/my.cnf:ro
      - mariadb_config:/etc/mysql:ro
      - mariadb_backup:/backups
      - /etc/localtime:/etc/localtime:ro
    labels:
      # Whats Up Docker
      - 'wud.watch=true'
      - 'wud.tag.include=^\d+\.\d+\.\d+$$'
    networks:
      - proxy_network
      - ha_network
    deploy:
      mode: replicated
      replicas: 1
      resources:
        limits:
          cpus: 4
          memory: 512M 
      update_config:
        parallelism: 2
        delay: 10s

# mariadb admin interface
# https://github.com/TimWolla/docker-adminer
# https://hub.docker.com/_/adminer/
  adminer:
    image: adminer:5.4.1 #4.17.1 #4.8.1
    container_name: "adminer"
    restart: unless-stopped
    #ports:
    #  - 8280:8080
    networks:
      - proxy_network
      - ha_network
    labels:
      - "traefik.enable=true"
      #- "traefik.docker.network=proxy"
      - "traefik.http.routers.adminer-secure.entrypoints=websecure"
      - "traefik.http.routers.adminer-secure.rule=Host(`adminer.nexusnet.me`)"
      - "traefik.http.routers.adminer-secure.tls=true"
      - "traefik.http.routers.adminer-secure.service=adminer"
      - "traefik.http.services.adminer.loadbalancer.server.port=8080"
      - "traefik.http.services.adminer.loadbalancer.server.scheme=http"
      # Whats Up Docker
      - 'wud.watch=true'
      - 'wud.tag.include=^\d+\.\d+\.\d+$$'
    deploy:
      mode: replicated
      replicas: 1
      resources:
        limits:
          cpus: 2
          memory: 50M 

secrets:
  influxdb2_ha-user:
    file: ./influxdb/secrets/influxdb2_ha-user.txt
  influxdb2_ha-user-password:
    file: ./influxdb/secrets/influxdb2_ha-user-password.txt
  influxdb2_admin-token:
    file: ./influxdb/secrets/influxdb2_admin-token.txt
  ha_mariadb_user:
    file: ./mariadb/secrets/ha_mariadb_user.txt
  ha_mariadb_user-password:
    file: ./mariadb/secrets/ha_mariadb_user-password.txt
  ha_mariadb_root-password:
    file: ./mariadb/secrets/ha_mariadb_root-password.txt
  #hass_configurator_password:
  #  external: true
  #hass_api_password:
  #  external: true

networks:
  proxy_network:
    external: true
  ha-macvlan_network:
    external: true
  ha_network:
    name: ha_network

volumes:
  ha_config:
    driver: local
    driver_opts:
      type: none
      o: bind
      device: /mnt/nvme-volume1/docker-apps/homeassistant/ha/volumes/config
  textcfg_config:
    driver: local
    driver_opts:
      type: none
      o: bind
      device: /mnt/nvme-volume1/docker-apps/homeassistant/textconfigurator/volumes/config
  influxdb_data:
    driver: local
    driver_opts:
      type: none
      o: bind
      device: /mnt/nvme-volume1/docker-apps/homeassistant/influxdb/volumes/data
  influxdb_config:
    driver: local
    driver_opts:
      type: none
      o: bind
      device: /mnt/nvme-volume1/docker-apps/homeassistant/influxdb/volumes/config
  grafana_config:
    driver: local
    driver_opts:
      type: none
      o: bind
      device: /mnt/nvme-volume1/docker-apps/homeassistant/grafana/volumes/config
  grafana_data:
    driver: local
    driver_opts:
      type: none
      o: bind
      device: /mnt/nvme-volume1/docker-apps/homeassistant/grafana/volumes/data
  mariadb_config:
    driver: local
    driver_opts:
      type: none
      o: bind
      device: /mnt/nvme-volume1/docker-apps/homeassistant/mariadb/volumes/config
  mariadb_data:
    driver: local
    driver_opts:
      type: none
      o: bind
      device: /mnt/nvme-volume1/docker-apps/homeassistant/mariadb/volumes/data
  mariadb_backup:
    driver: local
    driver_opts:
      type: none
      o: bind
      device: /mnt/nvme-volume1/docker-apps/homeassistant/mariadb/volumes/backup
  certs:
    driver: local
    driver_opts:
      type: none
      o: bind
      device: /mnt/nvme-volume1/docker-apps/certificates/certs

Update: from the shell in the ha container, I can resolved the container name of mariadb and also see that the port 3306 to it is open:

28d24dcafe7a:/config# nslookup ha-mariadb
Server:         127.0.0.11
Address:        127.0.0.11#53

Non-authoritative answer:
Name:   ha-mariadb
Address: 172.16.1.3
Name:   ha-mariadb
Address: fdd0:0:0:1::3

28d24dcafe7a:/config# nc -v ha-mariadb 3306
ha-mariadb (172.16.1.3:3306) open
Z
12.1.2-MariaDB-ubu2404g6th+=2~-=I2ZRi:&K*0R+mysql_native_password^Cpunt!

28d24dcafe7a:/config# 

I found this in the ha logs, which looks related to the db access error:

MySQLdb.OperationalError: (1045, "Access denied for user 'test1'@'172.16.1.15' (using password: YES)")
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
  File "/usr/src/homeassistant/homeassistant/components/recorder/core.py", line 916, in _setup_recorder
    self._setup_connection()
    ~~~~~~~~~~~~~~~~~~~~~~^^
  File "/usr/src/homeassistant/homeassistant/components/recorder/core.py", line 1434, in _setup_connection
    migration.pre_migrate_schema(self.engine)
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/components/recorder/migration.py", line 344, in pre_migrate_schema
    inspector = sqlalchemy.inspect(engine)
  File "/usr/local/lib/python3.13/site-packages/sqlalchemy/inspection.py", line 140, in inspect
    ret = reg(subject)
  File "/usr/local/lib/python3.13/site-packages/sqlalchemy/engine/reflection.py", line 313, in _engine_insp
    return Inspector._construct(Inspector._init_engine, bind)
           ~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.13/site-packages/sqlalchemy/engine/reflection.py", line 246, in _construct
    init(self, bind)
    ~~~~^^^^^^^^^^^^
  File "/usr/local/lib/python3.13/site-packages/sqlalchemy/engine/reflection.py", line 257, in _init_engine
    engine.connect().close()
    ~~~~~~~~~~~~~~^^
  File "/usr/local/lib/python3.13/site-packages/sqlalchemy/engine/base.py", line 3273, in connect
    return self._connection_cls(self)
           ~~~~~~~~~~~~~~~~~~~~^^^^^^
  File "/usr/local/lib/python3.13/site-packages/sqlalchemy/engine/base.py", line 147, in __init__
    Connection._handle_dbapi_exception_noconnection(
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^
        err, dialect, engine
        ^^^^^^^^^^^^^^^^^^^^
    )
    ^
  File "/usr/local/lib/python3.13/site-packages/sqlalchemy/engine/base.py", line 2436, in _handle_dbapi_exception_noconnection
    raise sqlalchemy_exception.with_traceback(exc_info[2]) from e
  File "/usr/local/lib/python3.13/site-packages/sqlalchemy/engine/base.py", line 145, in __init__
    self._dbapi_connection = engine.raw_connection()
                             ~~~~~~~~~~~~~~~~~~~~~^^
  File "/usr/local/lib/python3.13/site-packages/sqlalchemy/engine/base.py", line 3297, in raw_connection
    return self.pool.connect()
           ~~~~~~~~~~~~~~~~~^^
  File "/usr/local/lib/python3.13/site-packages/sqlalchemy/pool/base.py", line 449, in connect
    return _ConnectionFairy._checkout(self)
           ~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^
  File "/usr/local/lib/python3.13/site-packages/sqlalchemy/pool/base.py", line 1264, in _checkout
    fairy = _ConnectionRecord.checkout(pool)
  File "/usr/local/lib/python3.13/site-packages/sqlalchemy/pool/base.py", line 713, in checkout
    rec = pool._do_get()
  File "/usr/local/lib/python3.13/site-packages/sqlalchemy/pool/impl.py", line 179, in _do_get
    with util.safe_reraise():
         ~~~~~~~~~~~~~~~~~^^
  File "/usr/local/lib/python3.13/site-packages/sqlalchemy/util/langhelpers.py", line 224, in __exit__
    raise exc_value.with_traceback(exc_tb)
  File "/usr/local/lib/python3.13/site-packages/sqlalchemy/pool/impl.py", line 177, in _do_get
    return self._create_connection()
           ~~~~~~~~~~~~~~~~~~~~~~~^^
  File "/usr/local/lib/python3.13/site-packages/sqlalchemy/pool/base.py", line 390, in _create_connection
    return _ConnectionRecord(self)
  File "/usr/local/lib/python3.13/site-packages/sqlalchemy/pool/base.py", line 675, in __init__
    self.__connect()
    ~~~~~~~~~~~~~~^^
  File "/usr/local/lib/python3.13/site-packages/sqlalchemy/pool/base.py", line 901, in __connect
    with util.safe_reraise():
         ~~~~~~~~~~~~~~~~~^^
  File "/usr/local/lib/python3.13/site-packages/sqlalchemy/util/langhelpers.py", line 224, in __exit__
    raise exc_value.with_traceback(exc_tb)
  File "/usr/local/lib/python3.13/site-packages/sqlalchemy/pool/base.py", line 897, in __connect
    self.dbapi_connection = connection = pool._invoke_creator(self)
                                         ~~~~~~~~~~~~~~~~~~~~^^^^^^
  File "/usr/local/lib/python3.13/site-packages/sqlalchemy/engine/create.py", line 646, in connect
    return dialect.connect(*cargs, **cparams)
           ~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.13/site-packages/sqlalchemy/engine/default.py", line 625, in connect
    return self.loaded_dbapi.connect(*cargs, **cparams)  # type: ignore[no-any-return]  # NOQA: E501
           ~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.13/site-packages/MySQLdb/__init__.py", line 121, in Connect
    return Connection(*args, **kwargs)
  File "/usr/local/lib/python3.13/site-packages/MySQLdb/connections.py", line 200, in __init__
    super().__init__(*args, **kwargs2)
    ~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^
sqlalchemy.exc.OperationalError: (MySQLdb.OperationalError) (1045, "Access denied for user 'test1'@'172.16.1.15' (using password: YES)")
(Background on this error at: https://sqlalche.me/e/20/e3q8)
2026-01-12 01:37:01.691 ERROR (Recorder) [homeassistant.components.recorder.core] Error during connection setup: (retrying in 3 seconds)
Traceback (most recent call last):
  File "/usr/local/lib/python3.13/site-packages/sqlalchemy/engine/base.py", line 145, in __init__
    self._dbapi_connection = engine.raw_connection()
                             ~~~~~~~~~~~~~~~~~~~~~^^
  File "/usr/local/lib/python3.13/site-packages/sqlalchemy/engine/base.py", line 3297, in raw_connection
    return self.pool.connect()
           ~~~~~~~~~~~~~~~~~^^
  File "/usr/local/lib/python3.13/site-packages/sqlalchemy/pool/base.py", line 449, in connect
    return _ConnectionFairy._checkout(self)
           ~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^
  File "/usr/local/lib/python3.13/site-packages/sqlalchemy/pool/base.py", line 1264, in _checkout
    fairy = _ConnectionRecord.checkout(pool)
  File "/usr/local/lib/python3.13/site-packages/sqlalchemy/pool/base.py", line 713, in checkout
    rec = pool._do_get()
  File "/usr/local/lib/python3.13/site-packages/sqlalchemy/pool/impl.py", line 179, in _do_get
    with util.safe_reraise():
         ~~~~~~~~~~~~~~~~~^^
  File "/usr/local/lib/python3.13/site-packages/sqlalchemy/util/langhelpers.py", line 224, in __exit__
    raise exc_value.with_traceback(exc_tb)
  File "/usr/local/lib/python3.13/site-packages/sqlalchemy/pool/impl.py", line 177, in _do_get
    return self._create_connection()
           ~~~~~~~~~~~~~~~~~~~~~~~^^
  File "/usr/local/lib/python3.13/site-packages/sqlalchemy/pool/base.py", line 390, in _create_connection
    return _ConnectionRecord(self)
  File "/usr/local/lib/python3.13/site-packages/sqlalchemy/pool/base.py", line 675, in __init__
    self.__connect()
    ~~~~~~~~~~~~~~^^
  File "/usr/local/lib/python3.13/site-packages/sqlalchemy/pool/base.py", line 901, in __connect
    with util.safe_reraise():
         ~~~~~~~~~~~~~~~~~^^
  File "/usr/local/lib/python3.13/site-packages/sqlalchemy/util/langhelpers.py", line 224, in __exit__
    raise exc_value.with_traceback(exc_tb)
  File "/usr/local/lib/python3.13/site-packages/sqlalchemy/pool/base.py", line 897, in __connect
    self.dbapi_connection = connection = pool._invoke_creator(self)
                                         ~~~~~~~~~~~~~~~~~~~~^^^^^^
  File "/usr/local/lib/python3.13/site-packages/sqlalchemy/engine/create.py", line 646, in connect
    return dialect.connect(*cargs, **cparams)
           ~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.13/site-packages/sqlalchemy/engine/default.py", line 625, in connect
    return self.loaded_dbapi.connect(*cargs, **cparams)  # type: ignore[no-any-return]  # NOQA: E501
           ~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.13/site-packages/MySQLdb/__init__.py", line 121, in Connect
    return Connection(*args, **kwargs)
  File "/usr/local/lib/python3.13/site-packages/MySQLdb/connections.py", line 200, in __init__
    super().__init__(*args, **kwargs2)
    ~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^

I don’t think the HA log, reveal anything wrong in that end
So you might look at you user on the DB/Host, I see you have 2 places where you refer to user-passwd-file,in MariaDB container, and i assume the HOST ?
Are those identical credentials/rights ?

I was able to connect from HA shell using python and MySQLdb library with the test1 user. I used this article as a guide for that.
I’ll have another look to see if I can find out the actual credentials being used by the recorder. From initial checks it looks like they are the same in each environment though. (recorder URL, user/password files in MariaDb)

>>> database = MySQLdb.connect("ha-mariadb","test1","test2","homeassistant")
>>> print(database)
<_mysql.connection open to 'ha-mariadb' at 0x7ff4b1e4da30>
>>> cursor = database.cursor()
>>> cursor.execute("SELECT * from events LIMIT 10;")
10
>>> database.close()
>>> print(database)
<_mysql.connection closed at 0x7ff4b1e4da30>
>>> 

I’ve found the root cause. It was indeed the password in the recorder url.
I overlooked a full colon at the end of the password, just before the @ sign. At that position, it’s not a seperator char like it is between username and password etc.

recorder_db_url: 'mysql://test1:test2:@ha-mariadb:3306/homeassistant?charset=utf8mb4'

versus now working url:

recorder_db_url: 'mysql://test1:test2@ha-mariadb:3306/homeassistant?charset=utf8mb4'

Thank you very much boheme61 for your help and patience. :grinning:

It was in my first commend

I admit the colon is abit hard to notice