My system

  • Series of Ubuntu 14.04.5 (x86_64) Servers, kept updated
  • My application required I increase stack depth for postgres
  • I created a file in /etc/security/limits.d/myapplication.conf
  • The myapplication.conf file has the line: * - stack 131072
  • Note that 131072KB == 128MB
  • Upon making this myapplication.conf file, my ulimit -s returns: 131072
  • I then edited my /etc/postgresql/9.3/main/postgresql.conf file and appended the line: max_stack_depth = 126MB

My problem

During boot, the following message appears:

 * The PostgreSQL server failed to start. Please check the log output:
2018-01-24 09:27:53 MST LOG:  invalid value for parameter "max_stack_depth": 129024
2018-01-24 09:27:53 MST DETAIL:  "max_stack_depth" must not exceed 7680kB.
2018-01-24 09:27:53 MST HINT:  Increase the platform's stack depth limit via "ulimit -s" or local equivalent.
2018-01-24 09:27:53 MST FATAL:  configuration file "/etc/postgresql/9.3/main/postgresql.conf" contains errors
 * Starting Mount network filesystems                                    [ OK ]
 * Starting PostgreSQL 9.3 database server        * Stopping Mount networ[ OK ]systems

This in turn causes my application service to then fail, as I depend on my databases. After boot, if I start the postgres service, it's fine:

dev@wipn:~$ sudo service postgresql start
 * Starting PostgreSQL 9.3 database server                                                                                                                                                                                                                                                                             [ OK ] 

My guess is that the effects of /etc/security/limits.d/myapplication.conf are only applied at a stage during boot that's after when my system tries to start postgres. So, perhaps an obvious solution is to just change when I start postgres, that's fine and I can handle that.

My Question

What's a way to change the kernel's stack depth, such that I need only make minimal alterations to my servers?

I want something as clean as possible. I want it to withstand upgrades and preferably be applicable to other distros. I manage my stuff through Ansible plays, so I'd rather write one clean play for this.

It may simply be the case that changing start order of my services is the best resolution. Anyone out there know of other suitable options?

Things I've tried

Here's a list of some of the things I've tried, without success.

In /etc/security/limits.d/myapplication.conf:

  • postgres - stack 131072
  • * - stack 131072 root - stack 131072

2 Answers 2


Until someone can give me a clean solution, this is what I've come up with, and it sucks. I won't accept it as THE answer to my question, but here it is (gags). At least it works.


Seems that changes to /etc/security/limits.* never impact services, but rather stuff being executed from the shell. So, that kind of makes my changes in /etc/security/limits.* quite meaningless. (insert cussing here). I've now deleted my /etc/security/limits.d/myapplication.conf.

Changing Stack Size limits for postgres

This is a garbage solution. I hate it.

I've edited my "/usr/share/postgresql-common/init.d-functions", specifically the start() function, to appear as:

# start all clusters of version $1
# output according to Debian Policy for init scripts
start() {
    ulimit -s 131072    #JTS: To avoid Issue #XYZ 

    # create socket directory
    if [ -d /var/run/postgresql ]; then
        chmod 2775 /var/run/postgresql

Obviously I've added the ulimit line. It's disgusting to me to modify this file because I expect it to be perpetually changed by updates. At least I have an Ansible rule to enforce it exists.

My Ansible solution

Here's the Ansible task I've created to enforce this config change for me:

- blockinfile:
    dest: /usr/share/postgresql-common/init.d-functions
    block: |
          ulimit -s 131072
    backup: yes
    insertafter: '^start\(\) \{'
    state: present

This Ansible task results in the function looking like this:

# start all clusters of version $1
# output according to Debian Policy for init scripts
start() {
ulimit -s 131072
    # create socket directory
    if [ -d /var/run/postgresql ]; then

Of Note: Upstart Services Ignore /etc/security/limits

Seems that /etc/security/limits.* is ignorred by Upstart, which Ubuntu 14.04 uses. My application service actually uses upstart and one can insert a line for upstart that looks like:

limit stack <softlimit> <hardlimit>

Ubuntu switched to systemd after 14.04, so this upstart tid-bit will fade in to irrelevance.

This isn't relevant to my question because on 14.04, postgresql is not managed by upstart.


So I came here having the same issue and perhaps you find what I did more acceptable: My PostgreSQL runs as a systemd service. In the service file, I ve unlimited the stack from the OS's perspective:


In the postgresql.conf, I then set the following:

max_stack_depth = 100MB

This allowed to run my faulty recursive query for a few minutes, instead of a second.

I hope it helps you, event 1.5 years after your question.

(Postgresql 9.5.10 on Fedora 25)

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .