What is the maximum length of an environment variable?


A customer noticed that environment variables were being truncated at 2047 characters and wanted to know what the maximum length of an environment variable is.

This is one of those cases where you can answer the customer's question or you can try to answer the question the customer is really asking. If you just answer the question, you're doing the customer a disservice.

The theoretical maximum length of an environment variable is around 32,760 characters. However, you are unlikely to attain that theoretical maximum in practice.

All environment variables must live together in a single environment block, which itself has a limit of 32767 characters. But that count is the sum over all environment variable names and values, so you could, I guess, hit that theoretical maximum length if you deleted all the environment variables and then set a single variable called X with that really huge 32,760-character value. In practice, of course, you have to share the environment block with all the other variables in the block, so your random call to SetEnvironmentVariable with a 32,760-character string is unlikely to succeed.

But that's not your only practical limit.

It also depends on how you're setting the variable; i.e., the code that your environment-variable-setting technique passes through before it gets to the SetEnvironmentVariable call. If you're using a batch file, then you're constrained by the maximum command line length since the environment variable needs to fit into the command line buffer of the batch processor. On the other hand, maybe you're setting the Environment registry key, in which case you run into a 2048-character limit in the code that parses that registry key and builds an environment block out of it. There's also a limitation in the dialog box for interactively setting environment variables, the numeric value of which I don't happen to know off the top of my head.

This is one of those skills you have to develop when answering questions from customers: Taking the customer's question and trying to figure out what their real question is.

Comments (25)
  1. John Q Public says:

    It feels like the question that is really being asked is "Why isn’t there one answer to this question?"

  2. Paul says:

    And we can answer the question with a question:

    "A customer noticed that environment variables were being truncated at 2047 characters and wanted to know what the maximum length of an environment variable is."

    "Why? Why would you?!"

  3. Adrian says:

    Of course, the real question was, “How should I achieve such-and-such without something hacky like an environment variable?”

    [As I dimly recall, they were trying to set the PATH to longer than 2047 characters (but of course they didn’t mention that in their question). Good luck getting all programs on board with a replacement mechanism for path searching. -Raymond]
  4. Maurits says:

    What /was/ the real question?

  5. Jack Mathews says:

    Here’s the real question:

    What the hell are you doing setting a 2k environment variable?  This sounds like more the job of the %APPDATA% folder.

  6. laonianren says:

    "a single environment block, which itself has a limit of 32767 characters."

    This isn’t true (on XP at least), though it is what all the documentation says.  You can create megabytes of environment block and successfully pass it to a child process.  As far as I can tell, the 32K limit only applies if an environment block is converted from ANSI to UNICODE in CreateProcess.

    Also, the maximum command-line length isn’t strictly 8192 characters.  8192 is the length of a single cmd.exe buffer.  Lines of input, commands and their parameters are all stored in separate buffers.  A single command-line can be split across multiple input lines by escaping newline characters, and multiple commands can be joined with && (say).  In this way command-lines of unlimited length can be constructed.

  7. mpbk says:

    You will also run into another limit, which is the random size that various programs guess the environment variable will be.  For example, I’ve run into many programs that will crash if the PATH is too long.

  8. Kemp says:

    Maybe setting the PATH is an exception, but in general any question along the lines of "Why is the size of x limited to y?" or "Why does the system only let me create y of these objects?" means that they’re doing something wrong. A good followup is usually "Why would you possibly need to be hitting that limit?".

  9. Larry Lard says:

    Sounds like a prime candidate for a link to an earlier "If you have to ask what the limit is, you’re doing it wrong" post…

  10. MarcT says:

    @laonianren: That’s very interesting.

    Mal: Define "interesting".

    Wash: Oh God, oh God, we’re all going to die?

  11. 640k says:

    2047 characters is enough for everyone.

  12. Nick says:

    I’m suddenly filled with brillant ideas that nobody’s even considered before!

    For example, you could serialize a database to an environmental variable to make it easy to find and share between programs!

    This really brings the REAL question to light: Raymond, why can’t you easily store binary data in an environmental variable?  Shouldn’t there be some kind of ENV_BINARY or BLOB variable specification for enterprising developers?

    I also hope you’ve upped the limit from 32K characters in Win7.  A few gigabytes at least would be nice.

  13. Former Msft dev says:

    @ You can create megabytes of environment block and successfully pass it to a child process.

    The real problem is the process loader maps the passed-in environment block into the new process’s virtual address space, then maps something else into the next bit of virtual address space.

    As Raymond has noted before, GetEnvironmentXXX routines return the actual pointer to the environment block, making it unmoveable. Thus any attempts to expand the environment block run out of their bit of virtual address space. Thus a particular process can only grow its environment block by so much.

    That said, your child process (even another copy of yourself if you are so motivated) can have a huge environment block as long as you allocate and pass a big one when you create it.

  14. laonianren says:

    Former Msft dev: “GetEnvironmentXXX routines return the actual pointer to the environment block, making it unmoveable”.

    Windows moves it anyway.

    You can try this yourself: call GetEnvironmentStringsW and save the returned pointer to the environment block.  Create a few tens of thousands of environment variables and call GetEnvironmentStringsW again.  The block will have moved and the old pointer will reference unallocated memory.

    [Old news. -Raymond]
  15. Marquess says:

    The other question is of course: Should we still *use* environment variables?

  16. Marquess says:

    @Aram Hăvărneanu: "what else?"

    Well, there’s the registry, various types of IPC, %APPDATA%, %TEMP%, My Documents, …

  17. Andrei Vajna says:

    Isn’t the dialog box for editing the environment variables the same one as for editing Registry entries?

  18. A Lurker says:

    "There’s also a limitation in the dialog box for interactively setting environment variables, the numeric value of which I don’t happen to know off the top of my head."

    In Windows7 this happens to be 2047.

  19. Ryan says:

    @Nick: "This really brings the REAL question to light: Raymond, why can’t you easily store binary data in an environmental variable?  Shouldn’t there be some kind of ENV_BINARY or BLOB variable specification for enterprising developers?"

    How about BASE64/BASE32/Hex encoding? If you’re going to read binary data programmatically from an environment variable, you can certainly run it through a function too.

    Again, the question would be "Why?". If you need globally shared state period, and worse yet are using environment variables to achieve same, you’re probably doing something wrong.

  20. Magnus Hiie says:

    I think the limit on PATH environment variable is a valid concern. If you have dozens of apps installed, many of them including command-line programs, and the Windows model being that everything is stored in Program Files or …(x86), you really run out of space quickly. E.g. Windows SDK bin directory on x64 machine is 56 characters, which leaves you with a bit over 30 similar items to include in the path. I have way more I need to feel comfortable in the shells, so I really need to think what I want to include in the path and what not.

    Visual Studio answer for this is to invoke a batch file to set up the environment but this is really inconvenient.

    The unix approach is to have all executables in the few bin directories, I don’t think that’s a very good alternative either – allowing programs to install files in common directories causes a mess, I would really prefer the Windows approach if only there wasn’t a limit.

  21. Chris J says:

    Whenever presented with a question (customer or junior engineer) that basically is "I’m trying to do <low-level-thing-x>, but it isn’t working", I normal retaliate with the question: "What is it you’re *actually* trying to achieve?". Normally the answer to this highlights a fairly simple answer which they were trying to solve in a complicated way…

  22. Marquess says:

    Most programs don’t have to be in the path to be found. There’s a registry key for that. Path is only important for collections of programs (like SDKs, or ghostscript). I think that on Windows, the approach to have one executable for everything your application suite can do is better. Think net.exe.

  23. Theo V says:

    Kb 830473 has all the answers on command line length and environment variable lenght limitations, as well as a link to the relevant msdn article

    http://support.microsoft.com/default.aspx?scid=KB;EN-US;830473&ID=KB;EN-US;830473

  24. Gabe says:

    Magnus Hiie: You could just have a single directory with links to all your favorite utilities. A single directory per drive with hard links or a single directory period with sym links.

    Also, you could use somethine like ‘subst P: "C:Program Files(x86)"’ to make your PATH shorter. E.g. you could have P:Tools instead of C:Program Files(x86)Tools.

Comments are closed.