Unable to preview uploaded XLSForm on a self-hosted ODK Central installation

1. What is the issue? Please be detailed.

After installing ODK central on a Ubuntu 22.04.4 LTS server, we faced the below error message while trying to preview uploaded XLSForms.

"Loading Error
Error occured during the loading of this form. We do not recommend you use this form for data entry until this is resolved.

Please contact support@getodk.org with the link to this page and the error message below:

Failed to load form"

2. What steps can we take to reproduce this issue?

  • Log into ODK central
  • Navigate to projects
  • Go to a created Form
  • Click on preview
  • The system will open a new page with the above mentioned error message.

3. What have you tried to fix the issue?
We checked the logs of Enketo service, and below is the error message we noticed.

TypeError: HTTPConnection.request() got an unexpected keyword argument 'chunked'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
File "/usr/bin/docker-compose", line 33, in
sys.exit(load_entry_point('docker-compose==1.29.2', 'console_scripts', 'docker-compose')())
File "/usr/lib/python3/dist-packages/compose/cli/main.py", line 81, in main
command_func()
File "/usr/lib/python3/dist-packages/compose/cli/main.py", line 200, in perform_command
project = project_from_options('.', options)
File "/usr/lib/python3/dist-packages/compose/cli/command.py", line 60, in project_from_options
return get_project(
File "/usr/lib/python3/dist-packages/compose/cli/command.py", line 152, in get_project
client = get_client(
File "/usr/lib/python3/dist-packages/compose/cli/docker_client.py", line 41, in get_client
client = docker_client(
File "/usr/lib/python3/dist-packages/compose/cli/docker_client.py", line 170, in docker_client
client = APIClient(use_ssh_client=not use_paramiko_ssh, **kwargs)
File "/usr/lib/python3/dist-packages/docker/api/client.py", line 197, in init
self._version = self._retrieve_server_version()
File "/usr/lib/python3/dist-packages/docker/api/client.py", line 221, in _retrieve_server_version
raise DockerException(
docker.errors.DockerException: Error while fetching server API version: HTTPConnection.request() got an unexpected keyword argument 'chunked'

4. Upload any forms or screenshots you can share publicly below.

What version of Central are you using? To see your version, click on the question mark icon in the upper right section of your Central menu bar, then click Version. If you don't see the question mark, you can see the version by adding version.txt to the root URL (e.g., https://demo.getodk.cloud/version.txt).

What happens if you run this command? Does it print a 1, a 0, or nothing?

docker exec -it central-enketo-1 curl https://$(grep "^DOMAIN=" ~/central/.env | cut -d = -f 2) | grep -c getodk.org

Hi @yanokwa .

We are running v2023.5.1 as per the below version details.
versions:
20dcbf46703ded595b82bda713c624673a3faff9 (v2023.5.1)
+f34076ae9a1b74f7e928126a1dc2246eda2bb25f client (v2023.5.0-2-gf34076ae)
983ec81e69793fdb589ffdc346a16ef977489be4 server (v2023.5.0)

As for the output of the shared command, it is printing out a 0.

/odkcentral/central$ docker exec -it central-enketo-1 curl https://$(grep "^DOMAIN=" ~/central/.env | cut -d = -f 2) | grep -c getodk.org
0

The output of that command shows that the Enketo container can't reach the Nginx container over the Internet. Usually, this is because there is some internal DNS setting that isn't mapping yourdomain.com to the server. Perhaps your IT team can help.

Hello @yanokwa. Thanks again for your support on this. Actually, our domain is only accessible within our country. Might that be the cause? but again I see in the logs it's trying to call an external IP (192.168.16.9 on port 8005) , I wanted to understand why this? refer to the log portion bellow

nginx-1 | 2024/04/24 07:55:13 [error] 20#20: *2000 upstream timed out (110: Connection timed out) while reading response header from upstream, client: 172.80.4.8, server: local, request: "POST /-/transform/xform/OXzmCGrYEJhGPWDyhmJKditrYcevens HTTP/1.1",
"POST /-/transform/xform/OXzmCGrYEJhGPWDyhmJKditrYcevens HTTP/1.1", upstream: http://192.168.16.9:8005/-/transform/xform/OXzmCGrYEJhGPWDyhmJKditrYcevens",

I am having the same issue on my locally hosted ODK behind a nginx reverse proxy.

could the IP be the docker container IP that is assigned by docker to individual containers.
You can check container IPs using

docker inspect -f '{{.Name}} - {{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' $(docker ps -aq)

Hello @Dr_Vivek_Gupta
Could you please share the logs or any the error message you getting while trying to view the forms.

1 Like

Thanks Jackson. I have done a fresh installation in a VM and will be able to access logs tomorrow morning. I had shared logs in an earlier post

Here is my configuration please

Reverse Proxy

server {
 listen 443 ssl http2;
 server_name xxx.yyy.zzzz;
 ssl_certificate /etc/nginx/ssl/bundle.crt;
 ssl_certificate_key /etc/nginx/ssl/bundle.key;
 ssl_prefer_server_ciphers on;
 ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
 location / {
             proxy_pass "http://192.168.1.93:8080";
             proxy_set_header Host $host;
             proxy_set_header X-Real-IP $remote_addr;
             proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
             proxy_set_header X-Forwarded-Proto $scheme;
             proxy_buffering off;
             client_max_body_size 500M;
             proxy_connect_timeout       300;
             proxy_send_timeout          300;
             proxy_read_timeout          120;
             send_timeout                300;
          }
  }

server {
 listen 80;
 server_name xxx.yyy.zzzz;
 return 301 https://$host$request_uri;
}

Docker-compose.yml

services:
  postgres14:
    build:
      context: .
      dockerfile: postgres14.dockerfile
    volumes:
      - postgres14:/var/lib/odk/postgresql/14
    environment:
      POSTGRES_USER: odk
      POSTGRES_PASSWORD: odk
      POSTGRES_DB: odk
    restart: always
  postgres:
    # This service upgrades from postgres 9.6 to 14.
    # The legacy name must be maintained to allow access to the anonymous volume.
    build:
      context: .
      dockerfile: postgres-upgrade.dockerfile
    volumes:
      - /var/lib/postgresql/data
      - postgres14:/var/lib/postgresql/14
      - ./files/postgres14/upgrade:/postgres14-upgrade
    environment:
      PGUSER: odk
      POSTGRES_INITDB_ARGS: -U odk
      POSTGRES_PASSWORD: odk
      POSTGRES_DB: odk
  mail:
    image: "ixdotai/smtp:v0.5.2"
    volumes:
      - ./files/mail/rsa.private:/etc/exim4/dkim.key.temp:ro
    environment:
      - MAILNAME=${DOMAIN}
      - DKIM_KEY_PATH=/etc/exim4/dkim.key.temp
    restart: always
  service:
    build:
      context: .
      dockerfile: service.dockerfile
    depends_on:
      - secrets
      - postgres14
      - mail
      - pyxform
      - enketo
    volumes:
      - secrets:/etc/secrets
      - /data/transfer:/data/transfer
    environment:
      - DOMAIN=${DOMAIN}
      - SYSADMIN_EMAIL=${SYSADMIN_EMAIL}
      - HTTPS_PORT=${UPSTREAM_HTTPS_PORT:-443}
      - NODE_OPTIONS=${SERVICE_NODE_OPTIONS:-}
      - DB_HOST=${DB_HOST:-postgres14}
      - DB_USER=${DB_USER:-odk}
      - DB_PASSWORD=${DB_PASSWORD:-odk}
      - DB_NAME=${DB_NAME:-odk}
      - DB_SSL=${DB_SSL:-null}
      - EMAIL_FROM=${EMAIL_FROM:-no-reply@$DOMAIN}
      - EMAIL_HOST=${EMAIL_HOST:-mail}
      - EMAIL_PORT=${EMAIL_PORT:-25}
      - EMAIL_SECURE=${EMAIL_SECURE:-false}
     - EMAIL_IGNORE_TLS=${EMAIL_IGNORE_TLS:-true}
      - EMAIL_USER=${EMAIL_USER:-}
      - EMAIL_PASSWORD=${EMAIL_PASSWORD:-}
      - OIDC_ENABLED=${OIDC_ENABLED:-false}
      - OIDC_ISSUER_URL=${OIDC_ISSUER_URL:-}
      - OIDC_CLIENT_ID=${OIDC_CLIENT_ID:-}
      - OIDC_CLIENT_SECRET=${OIDC_CLIENT_SECRET:-}
      - SENTRY_ORG_SUBDOMAIN=${SENTRY_ORG_SUBDOMAIN:-o130137}
      - SENTRY_KEY=${SENTRY_KEY:-3cf75f54983e473da6bd07daddf0d2ee}
      - SENTRY_PROJECT=${SENTRY_PROJECT:-1298632}
    command: [ "wait-for-it", "${DB_HOST:-postgres14}:5432", "--", "./start-odk.sh" ]
    restart: always
    logging:
      driver: local
  nginx:
    build:
      context: .
      args:
        - OIDC_ENABLED=${OIDC_ENABLED:-false}
      dockerfile: nginx.dockerfile
    depends_on:
      - service
      - enketo
    environment:
      - DOMAIN=${DOMAIN}
      - CERTBOT_EMAIL=${SYSADMIN_EMAIL}
      - SSL_TYPE=${SSL_TYPE:-letsencrypt}
      - SENTRY_ORG_SUBDOMAIN=${SENTRY_ORG_SUBDOMAIN:-o130137}
      - SENTRY_KEY=${SENTRY_KEY:-3cf75f54983e473da6bd07daddf0d2ee}
      - SENTRY_PROJECT=${SENTRY_PROJECT:-1298632}
    ports:
      - "${HTTP_PORT:-80}:80"
      - "${HTTPS_PORT:-443}:443"
    healthcheck:
      test: [ "CMD-SHELL", "nc -z localhost 80 || exit 1" ]
    restart: always
    logging:
      driver: local
      options:
        max-file: "30"
  pyxform:
    image: 'ghcr.io/getodk/pyxform-http:v2.0.3'
    restart: always
  secrets:
    volumes:
      - secrets:/etc/secrets
    build:
      context: .
      dockerfile: secrets.dockerfile
    command: './generate-secrets.sh'
  enketo:
    volumes:
      - secrets:/etc/secrets
    build:
      context: .
      dockerfile: enketo.dockerfile
    restart: always
    depends_on:
      - secrets
      - enketo_redis_main
      - enketo_redis_cache
    environment:
      - DOMAIN=${DOMAIN}
      - SUPPORT_EMAIL=${SYSADMIN_EMAIL}
      - HTTPS_PORT=${UPSTREAM_HTTPS_PORT:-443}
  enketo_redis_main:
    image: redis:7.2
    volumes:
      - ./files/enketo/redis-enketo-main.conf:/usr/local/etc/redis/redis.conf:ro
      - enketo_redis_main:/data
    command:
      - redis-server
      - /usr/local/etc/redis/redis.conf
    restart: always
  enketo_redis_cache:
    image: redis:7.2
    volumes:
      - ./files/enketo/redis-enketo-cache.conf:/usr/local/etc/redis/redis.conf:ro
      - enketo_redis_cache:/data
    command:
      - redis-server
      - /usr/local/etc/redis/redis.conf
    restart: always
volumes:
  secrets:
  transfer:
  postgres14:
  enketo_redis_main:
  enketo_redis_cache:

.env

DOMAIN=xxx.yyy.zzzz
SYSADMIN_EMAIL=ccccc@gmail.com
SSL_TYPE=upstream
HTTP_PORT=8080
HTTPS_PORT=8443
UPSTREAM_HTTPS_PORT=443

My error is resolved
Details are documented here

Many Thanks to Yankowa, whose post above helped my pin point the error and to Jackson for the help offered

Best Wishes
Vivek