[Solved] Springboot upload failed to find the temporary directory error

The springboot upload failed to find the temporary directory and reported an error

1. Problem description

According to the feedback of online users, the upload file function suddenly reported an error. After checking the log file, the error message is:
failed to parse multipart servlet request; nested exception is java.lang.RuntimeException: java.nio.file.NoSuchFileException: /tmp/undertow.8099.1610110889708131476/undertow1171565914461190366upload

2. Cause investigation

Originally, when launching the spring boot application through java - jar in the linux operating system, a temporary directory will be created by default in the /tmp directory (in Windows operating system, C:\users\default\appdata\ local\temp), and the temporary directory is generally in the format of undertow. Port.* (if the Tomcat container is Tomcat.Port.*, this article will take undertow as an example, and Tomcat is the same.) , files need to be converted into temporary files and stored here when uploading. However, if the files in the /tmp directory are not used for more than 10 days, they will be automatically cleaned up by the system. Therefore, the above problems do not occur in the directory when uploading again.

3. Problem recurrence

Since the temporary directory will be created automatically when the service is started, restart the service in the local or test environment, delete the undertow.Port.* (if Tomcat, it is Tomcat.Port.*) directory generated under /tmp , and upload the file again.

4. Solution

1. Manually create the temporary directory (not recommended)

mkdir -p /tmp/undertow.8099.1610110889708131476/undertow1171565914461190366upload

PS: if the file is not uploaded for more than 10 days again, the same problem will occur. The symptoms are not the root cause.

2. Modify Linux system configuration (not recommended)

vim /usr/lib/tmpfiles.d/tmp.con
# Add at the end of the file, which means that the folder at the beginning of undertow will not be cleaned up
x /tmp/undertow*

PS: if multiple servers are deployed, each server needs to be modified.

3. Modify spring boot configuration file (recommended)

spring:
  servlet:
    multipart:
      # Specify a custom upload directory
      location: /mnt/tmp

PS: when using this method, you must ensure that /MNT/tmp exists. If it does not exist, the same error will occur. Therefore, it needs to be judged every time the service is started. If the directory exists, it will be ignored, and if it does not exist, it will be created. The code is as follows:

@Slf4j
@Configuration
public class MultipartConfig {

    @Value("${spring.servlet.multipart.location}")
    private String fileTempDir;

    @Bean
    MultipartConfigElement multipartConfigElement() {
        String os = System.getProperty("os.name");
        // windows
        if(os.toLowerCase().startsWith("win")){
            fileTempDir = "C:" + fileTempDir;
        }
        log.info("fileTempDir:{}", fileTempDir);
        MultipartConfigFactory factory = new MultipartConfigFactory();
        File tmpDirFile = new File(fileTempDir);
        // Determine whether the folder exists
         if (!tmpDirFile.exists()) {
             //Create folder
            boolean mkdirSuccess = tmpDirFile.mkdirs();
            log.info("create temp dir,result:{}", mkdirSuccess);
        }
        factory.setLocation(fileTempDir);
        return factory.createMultipartConfig();
    }

}

Read More: