Come for the products,
stay for the community

The Atlassian Community can help you and your team get more value out of Atlassian products and practices.

Atlassian Community about banner
4,365,885
Community Members
 
Community Events
168
Community Groups

Filename issue when using Jira Add Attachment REST API

We're using the following API to add attachments to Jira.

curl -D- -u {username}:{password} -X POST -H "X-Atlassian-Token: nocheck" -F "file=@{path/to/file}" http://{base-url}/rest/api/2/issue/{issue-key}/attachments

Unfortunately, if the filename contains square brackets, we get the following error.

<html>

<head>

<title>JIRA &mdash; Internal Server Error</title>

<meta name="decorator" content="none" />

</head>

<body>

<h1>JIRA &mdash; Internal Server Error</h1>

<p>Error reference: fc73345c-4f8a-4891-b866-bf7b09df7a54</p>

<p>Unable to render full error details at this time.

Please consult the error logs for more information.</p>

</body>

</html>

The error log has the following entry.

2022-09-06 13:13:27,095+1200 ajp-nio-127.0.0.1-8009-exec-33 url: /jira/rest/api/2/issue/ISSDDEV-306/attachments; user: dynamics-test WARN dynamics-test 793x286932x1 15xmvji 10.68.130.47 /rest/api/2/issue/ISSDDEV-306/attachments [c.a.j.issue.managers.DefaultAttachmentManager] Cannot create attachment without a filename - inline content? See http://jira.atlassian.com/browse/JRA-10825 (file=attachment-2654463909712498015.tmp).
2022-09-06 13:13:27,096+1200 ajp-nio-127.0.0.1-8009-exec-33 url: /jira/rest/api/2/issue/ISSDDEV-306/attachments; user: dynamics-test ERROR dynamics-test 793x286932x1 15xmvji 10.68.130.47 /rest/api/2/issue/ISSDDEV-306/attachments [c.a.j.r.v2.issue.IssueAttachmentsResource] Error saving attachment
java.lang.NullPointerException
        at com.atlassian.jira.issue.util.DefaultIssueUpdater.storeModifiedFields(DefaultIssueUpdater.java:104)
        at com.atlassian.jira.issue.util.DefaultIssueUpdater.doUpdate(DefaultIssueUpdater.java:94)
        at com.atlassian.jira.issue.util.DefaultIssueUpdater.doUpdate(DefaultIssueUpdater.java:63)
        at jdk.internal.reflect.GeneratedMethodAccessor3985.invoke(Unknown Source)
        at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
        at java.base/java.lang.reflect.Method.invoke(Unknown Source)
        at com.atlassian.plugin.util.ContextClassLoaderSettingInvocationHandler.invoke(ContextClassLoaderSettingInvocationHandler.java:26)
        at com.sun.proxy.$Proxy548.doUpdate(Unknown Source)
        at jdk.internal.reflect.GeneratedMethodAccessor3985.invoke(Unknown Source)
        at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
        at java.base/java.lang.reflect.Method.invoke(Unknown Source)
        at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:343)
        at org.eclipse.gemini.blueprint.service.importer.support.internal.aop.ServiceInvoker.doInvoke(ServiceInvoker.java:56)
        at org.eclipse.gemini.blueprint.service.importer.support.internal.aop.ServiceInvoker.invoke(ServiceInvoker.java:60)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
        at org.springframework.aop.support.DelegatingIntroductionInterceptor.doProceed(DelegatingIntroductionInterceptor.java:136)
        at org.springframework.aop.support.DelegatingIntroductionInterceptor.invoke(DelegatingIntroductionInterceptor.java:124)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
        at org.eclipse.gemini.blueprint.service.util.internal.aop.ServiceTCCLInterceptor.invokeUnprivileged(ServiceTCCLInterceptor.java:70)
        at org.eclipse.gemini.blueprint.service.util.internal.aop.ServiceTCCLInterceptor.invoke(ServiceTCCLInterceptor.java:53)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
        at org.eclipse.gemini.blueprint.service.importer.support.LocalBundleContextAdvice.invoke(LocalBundleContextAdvice.java:57)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
        at org.springframework.aop.support.DelegatingIntroductionInterceptor.doProceed(DelegatingIntroductionInterceptor.java:136)
        at org.springframework.aop.support.DelegatingIntroductionInterceptor.invoke(DelegatingIntroductionInterceptor.java:124)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
        at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:212)
        at com.sun.proxy.$Proxy3303.doUpdate(Unknown Source)
        at com.atlassian.jira.rest.v2.issue.IssueAttachmentsResource.addAttachment(IssueAttachmentsResource.java:128)
        at jdk.internal.reflect.GeneratedMethodAccessor3995.invoke(Unknown Source)
        at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
        at java.base/java.lang.reflect.Method.invoke(Unknown Source)
        ... 5 filtered
        at com.atlassian.jira.rest.exception.ExceptionInterceptor.intercept(ExceptionInterceptor.java:55)
        ... 1 filtered
        at com.atlassian.jira.rest.v2.issue.scope.RequestScopeInterceptor.intercept(RequestScopeInterceptor.java:39)
        ... 14 filtered
        at com.atlassian.plugins.rest.module.RestDelegatingServletFilter$JerseyOsgiServletContainer.doFilter(RestDelegatingServletFilter.java:160)
        ... 1 filtered
        at com.atlassian.plugins.rest.module.RestDelegatingServletFilter.doFilter(RestDelegatingServletFilter.java:70)
        ... 32 filtered
        at com.atlassian.servicedesk.internal.web.ExternalCustomerLockoutFilter.doFilter(ExternalCustomerLockoutFilter.java:55)
        ... 8 filtered
        at com.atlassian.jira.plugin.mobile.web.filter.MobileAppRequestFilter.doFilter(MobileAppRequestFilter.java:59)
        ... 4 filtered
        at com.atlassian.jira.plugin.mobile.login.MobileLoginSuccessFilter.doFilter(MobileLoginSuccessFilter.java:54)
        ... 3 filtered
        at com.atlassian.diagnostics.internal.platform.monitor.http.HttpRequestMonitoringFilter.doFilter(HttpRequestMonitoringFilter.java:55)
        ... 8 filtered
        at com.atlassian.web.servlet.plugin.request.RedirectInterceptingFilter.doFilter(RedirectInterceptingFilter.java:21)
        ... 43 filtered
        at com.atlassian.ratelimiting.internal.filter.RateLimitFilter.doFilter(RateLimitFilter.java:73)
        ... 3 filtered
        at com.atlassian.troubleshooting.thready.filter.AbstractThreadNamingFilter.doFilter(AbstractThreadNamingFilter.java:46)
        ... 17 filtered
        at com.atlassian.jira.security.JiraSecurityFilter.lambda$doFilter$0(JiraSecurityFilter.java:66)
        ... 1 filtered
        at com.atlassian.jira.security.JiraSecurityFilter.doFilter(JiraSecurityFilter.java:64)
        ... 16 filtered
        at com.atlassian.plugins.rest.module.servlet.RestSeraphFilter.doFilter(RestSeraphFilter.java:38)
        ... 3 filtered
        at com.atlassian.pats.web.filter.TokenBasedAuthenticationFilter.doFilter(TokenBasedAuthenticationFilter.java:83)
        ... 19 filtered
        at com.atlassian.jira.servermetrics.CorrelationIdPopulatorFilter.doFilter(CorrelationIdPopulatorFilter.java:30)
        ... 5 filtered
        at com.atlassian.plugins.authentication.impl.basicauth.filter.DisableBasicAuthFilter.doFilter(DisableBasicAuthFilter.java:70)
        ... 3 filtered
        at com.atlassian.servicedesk.internal.web.CustomerContextSettingFilter.lambda$invokeFilterChain$0(CustomerContextSettingFilter.java:215)
        at com.atlassian.servicedesk.internal.api.util.context.ReentrantThreadLocalBasedCodeContext.rteInvoke(ReentrantThreadLocalBasedCodeContext.java:136)
        at com.atlassian.servicedesk.internal.api.util.context.ReentrantThreadLocalBasedCodeContext.runOutOfContext(ReentrantThreadLocalBasedCodeContext.java:89)
        at com.atlassian.servicedesk.internal.utils.context.CustomerContextServiceImpl.runOutOfCustomerContext(CustomerContextServiceImpl.java:47)
        at com.atlassian.servicedesk.internal.web.CustomerContextSettingFilter.outOfCustomerContext(CustomerContextSettingFilter.java:206)
        at com.atlassian.servicedesk.internal.web.CustomerContextSettingFilter.doFilterImpl(CustomerContextSettingFilter.java:134)
        at com.atlassian.servicedesk.internal.web.CustomerContextSettingFilter.doFilter(CustomerContextSettingFilter.java:123)
        ... 4 filtered
        at com.atlassian.jwt.internal.servlet.JwtAuthFilter.doFilter(JwtAuthFilter.java:37)
        ... 8 filtered
        at com.atlassian.ratelimiting.internal.filter.RateLimitPreAuthFilter.doFilter(RateLimitPreAuthFilter.java:71)
        ... 3 filtered
        at com.atlassian.web.servlet.plugin.request.RedirectInterceptingFilter.doFilter(RedirectInterceptingFilter.java:21)
        ... 4 filtered
        at com.atlassian.troubleshooting.thready.filter.AbstractThreadNamingFilter.doFilter(AbstractThreadNamingFilter.java:46)
        ... 3 filtered
        at com.atlassian.web.servlet.plugin.LocationCleanerFilter.doFilter(LocationCleanerFilter.java:36)
        ... 26 filtered
        at com.atlassian.jira.servermetrics.MetricsCollectorFilter.doFilter(MetricsCollectorFilter.java:25)
        ... 25 filtered
        at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191)
        at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659)
        at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
        at java.base/java.lang.Thread.run(Unknown Source)
2022-09-06 13:13:27,141+1200 ajp-nio-127.0.0.1-8009-exec-18 url: /jira/rest/api/2/issue/ISSDDEV-306/attachments; user: dynamics-test WARN dynamics-test 793x286933x1 dnd57a 10.68.130.47 /rest/api/2/issue/ISSDDEV-306/attachments [c.a.j.issue.managers.DefaultAttachmentManager] Cannot create attachment without a filename - inline content? See http://jira.atlassian.com/browse/JRA-10825 (file=attachment-14328697622161150902.tmp).
2022-09-06 13:13:27,142+1200 ajp-nio-127.0.0.1-8009-exec-18 url: /jira/rest/api/2/issue/ISSDDEV-306/attachments; user: dynamics-test ERROR dynamics-test 793x286933x1 dnd57a 10.68.130.47 /rest/api/2/issue/ISSDDEV-306/attachments [c.a.j.r.v2.issue.IssueAttachmentsResource] Error saving attachment
java.lang.NullPointerException
        at com.atlassian.jira.issue.util.DefaultIssueUpdater.storeModifiedFields(DefaultIssueUpdater.java:104)
        at com.atlassian.jira.issue.util.DefaultIssueUpdater.doUpdate(DefaultIssueUpdater.java:94)
        at com.atlassian.jira.issue.util.DefaultIssueUpdater.doUpdate(DefaultIssueUpdater.java:63)
        at jdk.internal.reflect.GeneratedMethodAccessor3985.invoke(Unknown Source)
        at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
        at java.base/java.lang.reflect.Method.invoke(Unknown Source)
        at com.atlassian.plugin.util.ContextClassLoaderSettingInvocationHandler.invoke(ContextClassLoaderSettingInvocationHandler.java:26)
        at com.sun.proxy.$Proxy548.doUpdate(Unknown Source)
        at jdk.internal.reflect.GeneratedMethodAccessor3985.invoke(Unknown Source)
        at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
        at java.base/java.lang.reflect.Method.invoke(Unknown Source)
        at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:343)
        at org.eclipse.gemini.blueprint.service.importer.support.internal.aop.ServiceInvoker.doInvoke(ServiceInvoker.java:56)
        at org.eclipse.gemini.blueprint.service.importer.support.internal.aop.ServiceInvoker.invoke(ServiceInvoker.java:60)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
        at org.springframework.aop.support.DelegatingIntroductionInterceptor.doProceed(DelegatingIntroductionInterceptor.java:136)
        at org.springframework.aop.support.DelegatingIntroductionInterceptor.invoke(DelegatingIntroductionInterceptor.java:124)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
        at org.eclipse.gemini.blueprint.service.util.internal.aop.ServiceTCCLInterceptor.invokeUnprivileged(ServiceTCCLInterceptor.java:70)
        at org.eclipse.gemini.blueprint.service.util.internal.aop.ServiceTCCLInterceptor.invoke(ServiceTCCLInterceptor.java:53)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
        at org.eclipse.gemini.blueprint.service.importer.support.LocalBundleContextAdvice.invoke(LocalBundleContextAdvice.java:57)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
        at org.springframework.aop.support.DelegatingIntroductionInterceptor.doProceed(DelegatingIntroductionInterceptor.java:136)
        at org.springframework.aop.support.DelegatingIntroductionInterceptor.invoke(DelegatingIntroductionInterceptor.java:124)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
        at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:212)
        at com.sun.proxy.$Proxy3303.doUpdate(Unknown Source)
        at com.atlassian.jira.rest.v2.issue.IssueAttachmentsResource.addAttachment(IssueAttachmentsResource.java:128)
        at jdk.internal.reflect.GeneratedMethodAccessor3995.invoke(Unknown Source)
        at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
        at java.base/java.lang.reflect.Method.invoke(Unknown Source)
        ... 5 filtered
        at com.atlassian.jira.rest.exception.ExceptionInterceptor.intercept(ExceptionInterceptor.java:55)
        ... 1 filtered
        at com.atlassian.jira.rest.v2.issue.scope.RequestScopeInterceptor.intercept(RequestScopeInterceptor.java:39)
        ... 14 filtered
        at com.atlassian.plugins.rest.module.RestDelegatingServletFilter$JerseyOsgiServletContainer.doFilter(RestDelegatingServletFilter.java:160)
        ... 1 filtered
        at com.atlassian.plugins.rest.module.RestDelegatingServletFilter.doFilter(RestDelegatingServletFilter.java:70)
        ... 32 filtered
        at com.atlassian.servicedesk.internal.web.ExternalCustomerLockoutFilter.doFilter(ExternalCustomerLockoutFilter.java:55)
        ... 8 filtered
        at com.atlassian.jira.plugin.mobile.web.filter.MobileAppRequestFilter.doFilter(MobileAppRequestFilter.java:59)
        ... 4 filtered
        at com.atlassian.jira.plugin.mobile.login.MobileLoginSuccessFilter.doFilter(MobileLoginSuccessFilter.java:54)
        ... 3 filtered
        at com.atlassian.diagnostics.internal.platform.monitor.http.HttpRequestMonitoringFilter.doFilter(HttpRequestMonitoringFilter.java:55)
        ... 8 filtered
        at com.atlassian.web.servlet.plugin.request.RedirectInterceptingFilter.doFilter(RedirectInterceptingFilter.java:21)
        ... 43 filtered
        at com.atlassian.ratelimiting.internal.filter.RateLimitFilter.doFilter(RateLimitFilter.java:73)
        ... 3 filtered
        at com.atlassian.troubleshooting.thready.filter.AbstractThreadNamingFilter.doFilter(AbstractThreadNamingFilter.java:46)
        ... 17 filtered
        at com.atlassian.jira.security.JiraSecurityFilter.lambda$doFilter$0(JiraSecurityFilter.java:66)
        ... 1 filtered
        at com.atlassian.jira.security.JiraSecurityFilter.doFilter(JiraSecurityFilter.java:64)
        ... 16 filtered
        at com.atlassian.plugins.rest.module.servlet.RestSeraphFilter.doFilter(RestSeraphFilter.java:38)
        ... 3 filtered
        at com.atlassian.pats.web.filter.TokenBasedAuthenticationFilter.doFilter(TokenBasedAuthenticationFilter.java:83)
        ... 19 filtered
        at com.atlassian.jira.servermetrics.CorrelationIdPopulatorFilter.doFilter(CorrelationIdPopulatorFilter.java:30)
        ... 5 filtered
        at com.atlassian.plugins.authentication.impl.basicauth.filter.DisableBasicAuthFilter.doFilter(DisableBasicAuthFilter.java:70)
        ... 3 filtered
        at com.atlassian.servicedesk.internal.web.CustomerContextSettingFilter.lambda$invokeFilterChain$0(CustomerContextSettingFilter.java:215)
        at com.atlassian.servicedesk.internal.api.util.context.ReentrantThreadLocalBasedCodeContext.rteInvoke(ReentrantThreadLocalBasedCodeContext.java:136)
        at com.atlassian.servicedesk.internal.api.util.context.ReentrantThreadLocalBasedCodeContext.runOutOfContext(ReentrantThreadLocalBasedCodeContext.java:89)
        at com.atlassian.servicedesk.internal.utils.context.CustomerContextServiceImpl.runOutOfCustomerContext(CustomerContextServiceImpl.java:47)
        at com.atlassian.servicedesk.internal.web.CustomerContextSettingFilter.outOfCustomerContext(CustomerContextSettingFilter.java:206)
        at com.atlassian.servicedesk.internal.web.CustomerContextSettingFilter.doFilterImpl(CustomerContextSettingFilter.java:134)
        at com.atlassian.servicedesk.internal.web.CustomerContextSettingFilter.doFilter(CustomerContextSettingFilter.java:123)
        ... 4 filtered
        at com.atlassian.jwt.internal.servlet.JwtAuthFilter.doFilter(JwtAuthFilter.java:37)
        ... 8 filtered
        at com.atlassian.ratelimiting.internal.filter.RateLimitPreAuthFilter.doFilter(RateLimitPreAuthFilter.java:71)
        ... 3 filtered
        at com.atlassian.web.servlet.plugin.request.RedirectInterceptingFilter.doFilter(RedirectInterceptingFilter.java:21)
        ... 4 filtered
        at com.atlassian.troubleshooting.thready.filter.AbstractThreadNamingFilter.doFilter(AbstractThreadNamingFilter.java:46)
        ... 3 filtered
        at com.atlassian.web.servlet.plugin.LocationCleanerFilter.doFilter(LocationCleanerFilter.java:36)
        ... 26 filtered
        at com.atlassian.jira.servermetrics.MetricsCollectorFilter.doFilter(MetricsCollectorFilter.java:25)
        ... 25 filtered
        at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191)
        at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659)
        at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
        at java.base/java.lang.Thread.run(Unknown Source)
2022-09-06 13:13:27,388+1200 ajp-nio-127.0.0.1-8009-exec-32 url: /jira/rest/api/2/issue/ISSDDEV-306/attachments; user: dynamics-test INFO dynamics-test 793x286934x1 orq8l7 10.68.130.47 /rest/api/2/issue/ISSDDEV-306/attachments [c.a.jira.index.QueueingIndexStats] [JIRA-STATS] [INDEXING-QUEUE]  index:ISSUE, total primary queue stats: {"maxQueueSize":1,"putCounter":141,"queueFullOnPut":0,"getCounter":140,"timeInQueueMillis":{"count":140,"min":0,"max":6,"sum":39,"avg":0,"distributionCounter":{"0":114,"1":21,"10":5,"100":0,"1000":0,"10000":0,"20000":0,"30000":0}},"timeToUpdateIndexMillis":{"count":140,"min":0,"max":25,"sum":116,"avg":0,"distributionCounter":{"0":98,"1":32,"10":7,"50":3,"100":0,"500":0,"1000":0}},"totalTimeMillis":{"count":140,"min":1,"max":28,"sum":476,"avg":3,"distributionCounter":{"0":0,"1":12,"10":120,"100":8,"1000":0,"10000":0,"20000":0,"30000":0}},"totalTimeFailedMillis":{"count":0,"min":0,"max":0,"sum":0,"avg":0,"distributionCounter":{}},"totalTimeTimedOutMillis":{"count":0,"min":0,"max":0,"sum":0,"avg":0,"distributionCounter":{}},"putCounterByThreadTopN":{"ajp-nio-127.0.0.1-8009-exec-15 url: /jira/rest/jpo/1.0/issues/commit; user: ransa46p":8,"ajp-nio-127.0.0.1-8009-exec-27 url: /jira/rest/jpo/1.0/issues/commit; user: ransa46p":8,"ajp-nio-127.0.0.1-8009-exec-17 url: /jira/rest/jpo/1.0/issues/commit; user: ransa46p":6,"ajp-nio-127.0.0.1-8009-exec-18 url: /jira/rest/jpo/1.0/issues/commit; user: ransa46p":6,"ajp-nio-127.0.0.1-8009-exec-2 url: /jira/rest/jpo/1.0/issues/commit; user: ransa46p":6,"ajp-nio-127.0.0.1-8009-exec-21 url: /jira/rest/jpo/1.0/issues/commit; user: ransa46p":6,"ajp-nio-127.0.0.1-8009-exec-31 url: /jira/rest/jpo/1.0/issues/commit; user: ransa46p":6,"ajp-nio-127.0.0.1-8009-exec-13 url: /jira/rest/jpo/1.0/issues/commit; user: ransa46p":4,"ajp-nio-127.0.0.1-8009-exec-20 url: /jira/rest/jpo/1.0/issues/commit; user: ransa46p":4,"ajp-nio-127.0.0.1-8009-exec-26 url: /jira/rest/jpo/1.0/issues/commit; user: ransa46p":4},"indexerNotRunningCounter":0}
2022-09-06 13:13:27,388+1200 ajp-nio-127.0.0.1-8009-exec-32 url: /jira/rest/api/2/issue/ISSDDEV-306/attachments; user: dynamics-test INFO dynamics-test 793x286934x1 orq8l7 10.68.130.47 /rest/api/2/issue/ISSDDEV-306/attachments [c.a.jira.index.QueueingIndexStats] [JIRA-STATS] [INDEXING-QUEUE]  index:ISSUE, total secondary queue stats: {"maxQueueSize":2,"putCounter":10,"queueFullOnPut":0,"getCounter":10,"timeInQueueMillis":{"count":10,"min":0,"max":66,"sum":86,"avg":8,"distributionCounter":{"0":6,"1":0,"10":3,"100":1,"1000":0,"10000":0,"20000":0,"30000":0}},"timeToUpdateIndexMillis":{"count":10,"min":0,"max":66,"sum":104,"avg":10,"distributionCounter":{"0":3,"1":0,"10":5,"50":1,"100":1,"500":0,"1000":0}},"totalTimeMillis":{"count":10,"min":0,"max":69,"sum":196,"avg":19,"distributionCounter":{"0":1,"1":0,"10":5,"100":4,"1000":0,"10000":0,"20000":0,"30000":0}},"totalTimeFailedMillis":{"count":0,"min":0,"max":0,"sum":0,"avg":0,"distributionCounter":{}},"totalTimeTimedOutMillis":{"count":0,"min":0,"max":0,"sum":0,"avg":0,"distributionCounter":{}},"putCounterByThreadTopN":{"RMI TCP Connection(29)-10.68.1.47":3,"Caesium-1-4":2,"RMI TCP Connection(37)-10.68.1.47":2,"RMI TCP Connection(34)-10.68.1.47":1,"SdOffThreadEventJobRunner:thread-5":1,"devstatus.applink:thread-3":1},"indexerNotRunningCounter":0}
 

If we remove the square brackets from the filename, it is added to Jira successfully.

 

1 comment

Hello @Geoffrey Hughes 

Since Jira has no problems attaching files with square brackets in their name, then it can be logically deducted that the fault is in your cURL request.

Google 'cURL sanitise filenames' or 'cURL encode filenames' for the answer.

I just used curl as an example.  It's happening in Postman and with our integration platform.

Encoding the square brackets in my request does put the file into Jira but it keeps the encoded values when viewing in Jira.

Looking at how it's handled in a web browser, it's using a combination of 2 APIs. 

  • /rest/internal/2/AttachTemporaryFile
  • /rest/jddap/1.0/attachment

I just noticed you are still using Jira SERVER, not Jira CLOUD.

Uploading files with UTF-8 chars in their name is no problem with Jira Cloud. I just tested with Postman and a file named 'Test [file].txt' and it worked just fine:

Untitled.png

There are numerous articles regarding Jira Server and UTF-8 encoding issues with attachments, such as JRASERVER-32824. I think you should review the bugs list and see if a specific one affects your particular version of Jira Server and what you need to do to compensate for it.

 

I want to be able to submit a file with square brackets to Jira via the /rest/api/2/issue/{issue-key}/attachments rest API.

When I try in Postman, I get the internal server error I originally posted.

What version of Jira did you try against?  We're not using Jira cloud.

Can you send the output of the raw log from the Postman console?

As I said, I tested against Jira Cloud. I don't have access to a Jira Server instance at the moment and I no longer maintain my own instance.

For Jira Cloud I tested against both the v2 and v3 issue attachment endpoints and got the exact same result.

Here is the console log from Postman for a test against the v2 endpoint:

POST /rest/api/2/issue/BPT-232/attachments HTTP/1.1
X-Atlassian-Token: no-check
Authorization: Basic <--REDACTED-->
User-Agent: PostmanRuntime/7.29.2
Accept: */*
Cache-Control: no-cache
Postman-Token: 77ed735b-8694-4fe6-8eb2-42451a8eb982
Host: solidinterface.atlassian.net
Accept-Encoding: gzip, deflate, br
Connection: keep-alive
Content-Type: multipart/form-data; boundary=--------------------------524991648008426292662601
Cookie: atlassian.xsrf.token= <--REDACTED-->
Content-Length: 722

----------------------------524991648008426292662601
Content-Disposition: form-data; name="file"; filename="test [file].txt"
<test [file].txt>
----------------------------524991648008426292662601--

HTTP/1.1 200 OK
Date: Tue, 06 Sep 2022 23:23:28 GMT
Content-Type: application/json;charset=UTF-8
Server: globaledge-envoy
Timing-Allow-Origin: *
X-Arequestid: 783a9958-a97f-4e24-bc2f-88dbe817896f
X-Aaccountid: 5efea30ea115ac0bb540e9cb
Cache-Control: no-cache, no-store, no-transform
Vary: Accept-Encoding
Content-Encoding: br
X-Envoy-Upstream-Service-Time: 780
Expect-Ct: report-uri="https://web-security-reports.services.atlassian.com/expect-ct-report/atlassian-proxy", max-age=86400
Strict-Transport-Security: max-age=63072000; preload
X-Content-Type-Options: nosniff
X-Xss-Protection: 1; mode=block
Atl-Traceid: 534bf156eb348c83
Report-To: {"endpoints": [{"url": "https://dz8aopenkvv6s.cloudfront.net"}], "group": "endpoint-1", "include_subdomains": true, "max_age": 600}
Nel: {"failure_fraction": 0.001, "include_subdomains": true, "max_age": 600, "report_to": "endpoint-1"}
Transfer-Encoding: chunked

[{"self":"https://solidinterface.atlassian.net/rest/api/2/attachment/10017","id":"10017","filename":"test [file].txt","author":{"self":"https://solidinterface.atlassian.net/rest/api/2/user?accountId=5efea30ea115ac0bb540e9cb","accountId":"5efea30ea115ac0bb540e9cb","emailAddress":"asolidinterface@gmail.com","avatarUrls":{"48x48":"https://avatar-management--avatars.us-west-2.prod.public.atl-paas.net/5efea30ea115ac0bb540e9cb/c9e1b693-81bf-4eef-9848-3b844f31f01c/48","24x24":"https://avatar-management--avatars.us-west-2.prod.public.atl-paas.net/5efea30ea115ac0bb540e9cb/c9e1b693-81bf-4eef-9848-3b844f31f01c/24","16x16":"https://avatar-management--avatars.us-west-2.prod.public.atl-paas.net/5efea30ea115ac0bb540e9cb/c9e1b693-81bf-4eef-9848-3b844f31f01c/16","32x32":"https://avatar-management--avatars.us-west-2.prod.public.atl-paas.net/5efea30ea115ac0bb540e9cb/c9e1b693-81bf-4eef-9848-3b844f31f01c/32"},"displayName":"solid interface","active":true,"timeZone":"Australia/Sydney","accountType":"atlassian"},"created":"2022-09-07T09:23:28.203+1000","size":509,"mimeType":"text/plain","content":"https://solidinterface.atlassian.net/rest/api/2/attachment/content/10017"}]

 

Have fun.

PS. You are currently posting in the Discussion section of a public forum. If you have genuine technical problems with a specific API call to a specific version of Jira Server, you should be posting this as a Question in the Atlassian Developer's community.

Thanks.  I found my issue.  

Whomever setup the Postman collection added another Content-Type header without the boundary part of it.

Removing the second duplicate header and the Postman request has worked.

Comment

Log in or Sign up to comment