theonedev/onedev · error · NotAcceptableException

An active subscription is required for this feature

Error message

An active subscription is required for this feature

What it means

Setting data.getOwnEstimatedTime() on issue creation is an enterprise feature: createIssue throws NotAcceptableException("An active subscription is required for this feature") when subscriptionService.isSubscriptionActive() is false. Own estimated time is part of OneDev's paid time-tracking capability, so it is rejected on unlicensed (community) installs regardless of permissions.

Source

Thrown at server-core/src/main/java/io/onedev/server/rest/resource/IssueResource.java:322

		return issues;
	}

	@Api(order=1000)
    @POST
    public Long createIssue(@NotNull @Valid IssueOpenData data) {
		var subject = SecurityUtils.getSubject();
    	var user = SecurityUtils.getUser(subject);
    	
    	Project project = projectService.load(data.getProjectId());
    	if (!SecurityUtils.canAccessProject(project))
			throw new UnauthorizedException();

		if (data.getIterationIds() != null && !data.getIterationIds().isEmpty() && !SecurityUtils.canScheduleIssues(project))
			throw new UnauthorizedException("No permission to schedule issue. Remove iterationIds if you want to create issue without scheduling it.");

		if (data.getOwnEstimatedTime() != null) {
 			if (!subscriptionService.isSubscriptionActive())			
				throw new NotAcceptableException("An active subscription is required for this feature");
			if (!project.isTimeTracking())
				throw new NotAcceptableException("Time tracking needs to be enabled for the project");
			if (!SecurityUtils.canScheduleIssues(project))
				throw new UnauthorizedException("Issue schedule permission required to set own estimated time. Remove ownEstimatedTime if you want to create issue without setting own estimated time.");
		}

		var issueSetting = settingService.getIssueSetting();
		
		Issue issue = new Issue();
		issue.setTitle(data.getTitle());
		issue.setDescription(data.getDescription());
		issue.setConfidential(data.isConfidential());
		issue.setProject(project);
		issue.setSubmitDate(new Date());
		issue.setSubmitter(user);
		issue.setState(issueSetting.getInitialStateSpec().getName());
		if (data.getOwnEstimatedTime() != null)
			issue.setOwnEstimatedTime(data.getOwnEstimatedTime());

View on GitHub (pinned to d44925c47c)

Solutions

  1. Remove ownEstimatedTime from the request payload.
  2. Purchase/restore an active OneDev enterprise subscription and install the license.
  3. Track estimated time in a custom issue field instead if you are on community edition.
  4. Verify subscription status via the admin console before re-enabling time-tracking automation.

Example fix

// before
POST /~api/issues {"projectId":1, "title":"x", "ownEstimatedTime":3600}
// after (no subscription)
POST /~api/issues {"projectId":1, "title":"x"}
Defensive patterns

Strategy: validation

Validate before calling

// only send ownEstimatedTime when the instance is subscribed
if (!subscriptionActive) {
    data.setOwnEstimatedTime(null); // feature requires enterprise subscription
}

Try / catch

try { client.createIssue(data); }
catch (NotAcceptableException e) {
    if (e.getMessage().contains("subscription")) { data.setOwnEstimatedTime(null); client.createIssue(data); }
}

Prevention

When it happens

Trigger: POST /~api/issues with ownEstimatedTime set on a server without an active enterprise subscription (trial expired, license removed, or community edition).

Common situations: Scripts written against a licensed staging instance then run against community production; subscription expired and silently downgraded; feature flag confusion between community and enterprise endpoints.

Related errors


AI-assisted analysis of theonedev/onedev@d44925c47c (2026-09-06). Data as JSON: /api/errors/b268578e30bbfe80. Report an issue: GitHub.