Thread

  1. BUG #19028: INITDB fails post-bootstrap initialization with FATAL " " is not a valid binary digit at character 1

    PG Bug reporting form <noreply@postgresql.org> — 2025-08-21T04:53:52Z

    The following bug has been logged on the website:
    
    Bug reference:      19028
    Logged by:          Ayoub Kazar
    Email address:      ma_kazar@esi.dz
    PostgreSQL version: 18beta3
    Operating system:   Ubuntu 22.04.4 LTS
    Description:        
    
    Hi everyone,
    
    This is from current master branch, compiled with ./configure
    --prefix=/home/ayoubkaz/pg_new_master --enable-debug CFLAGS='-O2 -g'
    Error from INITDB:
    postgres git:(master) ✗ /home/ayoubkaz/pg_new_master/bin/initdb -D
    /home/ayoubkaz/pg_new_master_data
    The files belonging to this database system will be owned by user
    "ayoubkaz".
    This user must also own the server process.
    
    The database cluster will be initialized with locale "en_US.utf8".
    The default database encoding has accordingly been set to "UTF8".
    The default text search configuration will be set to "english".
    
    Data page checksums are enabled.
    
    creating directory /home/ayoubkaz/pg_new_master_data ... ok
    creating subdirectories ... ok
    selecting dynamic shared memory implementation ... posix
    selecting default "max_connections" ... 100
    selecting default "shared_buffers" ... 128MB
    selecting default time zone ... Africa/Algiers
    creating configuration files ... ok
    running bootstrap script ... ok
    performing post-bootstrap initialization ... 2025-08-21 03:43:47.341 CET
    [199047] FATAL:  " " is not a valid binary digit at character 1670
    2025-08-21 03:43:47.341 CET [199047] STATEMENT:
    	
            /*
             * PostgreSQL System Functions
             *
             * Copyright (c) 1996-2025, PostgreSQL Global Development Group
             *
             * src/backend/catalog/system_functions.sql
             *
             * This file redefines certain built-in functions that are
    impractical
             * to fully define in pg_proc.dat.  In most cases that's because
    they use
             * SQL-standard function bodies and/or default expressions.  The
    node
             * tree representations of those are too unreadable,
    platform-dependent,
             * and changeable to want to deal with them manually.  Hence, we put
    stub
             * definitions of such functions into pg_proc.dat and then replace
    them
             * here.  The stub definitions would be unnecessary were it not that
    we'd
             * like these functions to have stable OIDs, the same as other
    built-in
             * functions.
             *
             * This file also takes care of adjusting privileges for those
    functions
             * that should not have the default public-EXECUTE privileges.
    (However,
             * a small number of functions that exist mainly to underlie system
    views
             * are dealt with in system_views.sql, instead.)
             *
             * Note: this file is read in single-user -j mode, which means that
    the
             * command terminator is semicolon-newline-newline; whenever the
    backend
             * sees that, it stops and executes what it's got.  If you write a
    lot of
             * statements without empty lines between, they'll all get quoted to
    you
             * in any error message about one of them, so don't do that.  Also,
    you
             * cannot write a semicolon immediately followed by an empty line in
    a
             * string literal (including a function body!) or a multiline
    comment.
             */
    	
    	
            CREATE OR REPLACE FUNCTION lpad(text, integer)
             RETURNS text
             LANGUAGE sql
             IMMUTABLE PARALLEL SAFE STRICT COST 1
            RETURN lpad($1, $2, ' ');
    	
    child process exited with exit code 1
    initdb: removing data directory "/home/ayoubkaz/pg_new_master_data"
    
    Initdb runs post-bootstrap initialization sql files like constraints,
    functions and views .... using a cmd piped postgres backend in single mode.
    Currently it fails at system functions initialization "setup_run_file(cmdfd,
    system_functions_file);"
    
    After checking with actual sql files and perl script generating system
    constraints file just to make sure they all follow the rules of
    initialization, they look good.
    
    Using gdb we can see the moment where it fails at setup_run_file with a
    SIGPIPE
    
    1732            for (char **line = lines; *line != NULL; line++)
    (gdb) p *line
    $2 = 0x5555555a6960 "RETURN lpad($1, $2, ' ');\n"
    (gdb) n
    1734                    PG_CMD_PUTS(*line);
    (gdb)
    1735                    free(*line);
    (gdb)
    1732            for (char **line = lines; *line != NULL; line++)
    (gdb)
    1734                    PG_CMD_PUTS(*line);
    (gdb) p *line
    $4 = 0x5555555a54a0 "\n"
    (gdb) print *cmdfd
    $5 = {_flags = -72536956,
      _IO_read_ptr = 0x5555555aeeb0 "RETURN lpad($1, $2, ' ');\nTRICT COST
    1\nnteger)\nor a multiline
    comment.\n\n\n\nn_rel_srrelid_srsubid_index;\ndex;\noint_left _null_ _null_
    _null_ _null\240",
      _IO_read_end = 0x5555555aeeb0 "RETURN lpad($1, $2, ' ');\nTRICT COST
    1\nnteger)\nor a multiline
    comment.\n\n\n\nn_rel_srrelid_srsubid_index;\ndex;\noint_left _null_ _null_
    _null_ _null\240",
      _IO_read_base = 0x5555555aeeb0 "RETURN lpad($1, $2, ' ');\nTRICT COST
    1\nnteger)\nor a multiline
    comment.\n\n\n\nn_rel_srrelid_srsubid_index;\ndex;\noint_left _null_ _null_
    _null_ _null\240",
      _IO_write_base = 0x5555555aeeb0 "RETURN lpad($1, $2, ' ');\nTRICT COST
    1\nnteger)\nor a multiline
    comment.\n\n\n\nn_rel_srrelid_srsubid_index;\ndex;\noint_left _null_ _null_
    _null_ _null\240",
      _IO_write_ptr = 0x5555555aeeb0 "RETURN lpad($1, $2, ' ');\nTRICT COST
    1\nnteger)\nor a multiline
    comment.\n\n\n\nn_rel_srrelid_srsubid_index;\ndex;\noint_left _null_ _null_
    _null_ _null\240",
      _IO_write_end = 0x5555555afeb0 " _null_ 1",
      _IO_buf_base = 0x5555555aeeb0 "RETURN lpad($1, $2, ' ');\nTRICT COST
    1\nnteger)\nor a multiline
    comment.\n\n\n\nn_rel_srrelid_srsubid_index;\ndex;\noint_left _null_ _null_
    _null_ _null\240",
      _IO_buf_end = 0x5555555afeb0 " _null_ 1", _IO_save_base = 0x0,
    _IO_backup_base = 0x0, _IO_save_end = 0x0, _markers = 0x0, _chain =
    0x7ffff7c1b6a0 <_IO_2_1_stderr_>, _fileno = 4, _flags2 = 0,
      _old_offset = 8010900073819696940, _cur_column = 0, _vtable_offset = 32 '
    ', _shortbuf = "'", _lock = 0x5555555a5940, _offset = -1, _codecvt =
    0x63612c657a69732c, _wide_data = 0xffffffffffffffff,
      _freeres_list = 0x0, _freeres_buf = 0x65676e6168632c6e, __pad5 =
    8028075772427264812, _mode = -1, _unused2 = "dir}' _null_ _null_ "}
    (gdb) n
    2025-08-21 04:00:09.272 CET [200703] FATAL:  " " is not a valid binary digit
    at character 1670
    2025-08-21 04:00:09.272 CET [200703] STATEMENT:
    	
            /*
             * PostgreSQL System Functions
             *
             * Copyright (c) 1996-2025, PostgreSQL Global Development Group
             *
             * src/backend/catalog/system_functions.sql
             *
             * This file redefines certain built-in functions that are
    impractical
             * to fully define in pg_proc.dat.  In most cases that's because
    they use
             * SQL-standard function bodies and/or default expressions.  The
    node
             * tree representations of those are too unreadable,
    platform-dependent,
             * and changeable to want to deal with them manually.  Hence, we put
    stub
             * definitions of such functions into pg_proc.dat and then replace
    them
             * here.  The stub definitions would be unnecessary were it not that
    we'd
             * like these functions to have stable OIDs, the same as other
    built-in
             * functions.
             *
             * This file also takes care of adjusting privileges for those
    functions
             * that should not have the default public-EXECUTE privileges.
    (However,
             * a small number of functions that exist mainly to underlie system
    views
             * are dealt with in system_views.sql, instead.)
             *
             * Note: this file is read in single-user -j mode, which means that
    the
             * command terminator is semicolon-newline-newline; whenever the
    backend
             * sees that, it stops and executes what it's got.  If you write a
    lot of
             * statements without empty lines between, they'll all get quoted to
    you
             * in any error message about one of them, so don't do that.  Also,
    you
             * cannot write a semicolon immediately followed by an empty line in
    a
             * string literal (including a function body!) or a multiline
    comment.
             */
    	
    	
            CREATE OR REPLACE FUNCTION lpad(text, integer)
             RETURNS text
             LANGUAGE sql
             IMMUTABLE PARALLEL SAFE STRICT COST 1
            RETURN lpad($1, $2, ' ');
    	
    1735                    free(*line);
    (gdb) n
    1732            for (char **line = lines; *line != NULL; line++)
    (gdb)
    1734                    PG_CMD_PUTS(*line);
    (gdb)
    
    Program received signal SIGPIPE, Broken pipe.
    0x00007ffff7b14887 in __GI___libc_write (fd=4, buf=0x5555555aeeb0,
    nbytes=47) at ../sysdeps/unix/sysv/linux/write.c:26
    26      ../sysdeps/unix/sysv/linux/write.c: No such file or directory.
    (gdb)
    
    This happens right at PG_CMD_PUTS('\n') this is the second expected newline
    after a command (here it's the first command in system_functions)
    
    Went down with gdb for postgres process, and indeed i reach this
    transformExprRecurse (pstate=0x5555560b14a0, expr=0x55555613f9f8) at
    parse_expr.c:137
    137     {
    (gdb) n
    140             if (expr == NULL)
    (gdb)
    144             check_stack_depth();
    (gdb)
    146             switch (nodeTag(expr))
    (gdb)
    157                             result = (Node *) make_const(pstate,
    (A_Const *) expr);
    (gdb) step
    make_const (pstate=0x5555560b14a0, aconst=0x55555613f9f8) at
    parse_node.c:348
    348     {
    (gdb) n
    356             if (aconst->isnull)
    (gdb)
    370             switch (nodeTag(&aconst->val))
    (gdb)
    454                             setup_parser_errposition_callback(&pcbstate,
    pstate, aconst->location);
    (gdb)
    144             pcbstate->pstate = pstate;
    (gdb)
    454                             setup_parser_errposition_callback(&pcbstate,
    pstate, aconst->location);
    (gdb)
    145             pcbstate->location = location;
    (gdb)
    454                             setup_parser_errposition_callback(&pcbstate,
    pstate, aconst->location);
    (gdb) n
    334             return (Datum) (uintptr_t) X;
    (gdb) step
    DirectFunctionCall3Coll (func=0x555555b4da00 <bit_in>,
    collation=collation@entry=0, arg1=93825004730856, arg2=arg2@entry=0,
    arg3=arg3@entry=18446744073709551615) at fmgr.c:836
    836     {
    (gdb) n
    840             InitFunctionCallInfoData(*fcinfo, NULL, 3, collation, NULL,
    NULL);
    (gdb)
    849             result = (*func) (fcinfo);
    (gdb)
    [Inferior 1 (process 210169) exited with code 01]
    
    This is for the 3rd function argument with making Datum in bit_in (which i
    don't understand why) matches the error " " is not a valid binary digit at
    character 1670 from "RETURN lpad($1, $2, ' ');"
    
    Also a week older master compilation doesn't have this issue, so this should
    narrow down the hunt for someone if this isn't something only i am seeing,
    i'll leave it to someone who knows more about this region.
    
    
    Best regards,
    Ayoub Kazar
    
    
  2. Re: BUG #19028: INITDB fails post-bootstrap initialization with FATAL " " is not a valid binary digit at character 1

    KAZAR Ayoub <ma_kazar@esi.dz> — 2025-08-21T05:03:39Z

    This was fixed after doing a clean compilation of master which i forgot
    about only after reporting it, this bug is not valid anymore while i still
    find it interesting to understand the reason why it was happening.
    
    
    Regards,
    Ayoub Kazar
    
  3. Re: BUG #19028: INITDB fails post-bootstrap initialization with FATAL " " is not a valid binary digit at character 1

    Thomas Munro <thomas.munro@gmail.com> — 2025-08-22T02:16:40Z

    On Thu, Aug 21, 2025 at 5:03 PM KAZAR Ayoub <ma_kazar@esi.dz> wrote:
    > This was fixed after doing a clean compilation of master which i forgot about only after reporting it, this bug is not valid anymore while i still find it interesting to understand the reason why it was happening.
    
    I vaguely recall problems when lexer or parser code had been generated
    by different binaries, when I'd changed the PATH or upgraded some
    packages or something like that.  (Older branches had a related
    footgun built in, see 721856ff, but you said this is master.)  The
    symptom I recall was a psql that would crash in the slash lexer so may
    be completely unrelated... just mentioning it since you said a clean
    build did the trick.