diff --git a/routers/web/repo/activity.go b/routers/web/repo/activity.go
index 6f6641cc65..ba776c84d3 100644
--- a/routers/web/repo/activity.go
+++ b/routers/web/repo/activity.go
@@ -57,7 +57,7 @@ func Activity(ctx *context.Context) {
 		ctx.Repo.CanRead(unit.TypeReleases),
 		ctx.Repo.CanRead(unit.TypeIssues),
 		ctx.Repo.CanRead(unit.TypePullRequests),
-		ctx.Repo.CanRead(unit.TypeCode)); err != nil {
+		ctx.Repo.CanRead(unit.TypeCode) && !ctx.Repo.Repository.IsEmpty); err != nil {
 		ctx.ServerError("GetActivityStats", err)
 		return
 	}
diff --git a/routers/web/web.go b/routers/web/web.go
index 1d085a37cb..23695ee4db 100644
--- a/routers/web/web.go
+++ b/routers/web/web.go
@@ -1423,16 +1423,16 @@ func registerRoutes(m *web.Route) {
 			m.Group("/contributors", func() {
 				m.Get("", repo.Contributors)
 				m.Get("/data", repo.ContributorsData)
-			})
+			}, repo.MustBeNotEmpty, context.RequireRepoReaderOr(unit.TypeCode))
 			m.Group("/code-frequency", func() {
 				m.Get("", repo.CodeFrequency)
 				m.Get("/data", repo.CodeFrequencyData)
-			})
+			}, repo.MustBeNotEmpty, context.RequireRepoReaderOr(unit.TypeCode))
 			m.Group("/recent-commits", func() {
 				m.Get("", repo.RecentCommits)
 				m.Get("/data", repo.RecentCommitsData)
-			})
-		}, context.RepoRef(), repo.MustBeNotEmpty, context.RequireRepoReaderOr(unit.TypePullRequests, unit.TypeIssues, unit.TypeReleases))
+			}, repo.MustBeNotEmpty, context.RequireRepoReaderOr(unit.TypeCode))
+		}, context.RepoRef(), context.RequireRepoReaderOr(unit.TypeCode, unit.TypePullRequests, unit.TypeIssues, unit.TypeReleases))
 
 		m.Group("/activity_author_data", func() {
 			m.Get("", repo.ActivityAuthors)
diff --git a/templates/repo/activity.tmpl b/templates/repo/activity.tmpl
index a19fb66261..19a09b99b0 100644
--- a/templates/repo/activity.tmpl
+++ b/templates/repo/activity.tmpl
@@ -2,9 +2,11 @@
 <div role="main" aria-label="{{.Title}}" class="page-content repository commits">
 	{{template "repo/header" .}}
 	<div class="ui container flex-container">
-		<div class="flex-container-nav">
-			{{template "repo/navbar" .}}
-		</div>
+		{{if and (not .IsEmptyRepo) (.Permission.CanRead $.UnitTypeCode)}}
+			<div class="flex-container-nav">
+				{{template "repo/navbar" .}}
+			</div>
+		{{end}}
 		<div class="flex-container-main">
 			{{if .PageIsPulse}}{{template "repo/pulse" .}}{{end}}
 			{{if .PageIsContributors}}{{template "repo/contributors" .}}{{end}}
diff --git a/templates/repo/header.tmpl b/templates/repo/header.tmpl
index 95c2e059d5..cf8ee7d772 100644
--- a/templates/repo/header.tmpl
+++ b/templates/repo/header.tmpl
@@ -159,7 +159,7 @@
 					</a>
 				{{end}}
 
-				{{if and (.Permission.CanReadAny $.UnitTypePullRequests $.UnitTypeIssues $.UnitTypeReleases) (not .IsEmptyRepo)}}
+				{{if and (.Permission.CanReadAny $.UnitTypeCode $.UnitTypePullRequests $.UnitTypeIssues $.UnitTypeReleases)}}
 					<a class="{{if .PageIsActivity}}active {{end}}item" href="{{.RepoLink}}/activity">
 						{{svg "octicon-pulse"}} {{ctx.Locale.Tr "repo.activity"}}
 					</a>
diff --git a/tests/integration/repo_activity_test.go b/tests/integration/repo_activity_test.go
index 792554db4b..0b1e9939a1 100644
--- a/tests/integration/repo_activity_test.go
+++ b/tests/integration/repo_activity_test.go
@@ -4,13 +4,20 @@
 package integration
 
 import (
+	"fmt"
 	"net/http"
 	"net/url"
 	"strings"
 	"testing"
 
+	"code.gitea.io/gitea/models/db"
 	repo_model "code.gitea.io/gitea/models/repo"
+	unit_model "code.gitea.io/gitea/models/unit"
+	"code.gitea.io/gitea/models/unittest"
+	user_model "code.gitea.io/gitea/models/user"
 	"code.gitea.io/gitea/modules/test"
+	repo_service "code.gitea.io/gitea/services/repository"
+	"code.gitea.io/gitea/tests"
 
 	"github.com/stretchr/testify/assert"
 )
@@ -63,3 +70,122 @@ func TestRepoActivity(t *testing.T) {
 		assert.Len(t, list.Nodes, 3)
 	})
 }
+
+func TestRepoActivityAllUnitsDisabled(t *testing.T) {
+	defer tests.PrepareTestEnv(t)()
+	user := unittest.AssertExistsAndLoadBean(t, &user_model.User{Name: "user1"})
+	session := loginUser(t, user.Name)
+
+	unit_model.LoadUnitConfig()
+
+	// Create a repo, with no unit enabled.
+	repo, err := repo_service.CreateRepository(db.DefaultContext, user, user, repo_service.CreateRepoOptions{
+		Name:     "empty-repo",
+		AutoInit: false,
+	})
+	assert.NoError(t, err)
+	assert.NotEmpty(t, repo)
+
+	enabledUnits := make([]repo_model.RepoUnit, 0)
+	disabledUnits := []unit_model.Type{unit_model.TypeCode, unit_model.TypeIssues, unit_model.TypePullRequests, unit_model.TypeReleases}
+	err = repo_service.UpdateRepositoryUnits(db.DefaultContext, repo, enabledUnits, disabledUnits)
+	assert.NoError(t, err)
+
+	req := NewRequest(t, "GET", fmt.Sprintf("%s/activity", repo.Link()))
+	session.MakeRequest(t, req, http.StatusNotFound)
+	req = NewRequest(t, "GET", fmt.Sprintf("%s/activity/contributors", repo.Link()))
+	session.MakeRequest(t, req, http.StatusNotFound)
+	req = NewRequest(t, "GET", fmt.Sprintf("%s/activity/code-frequency", repo.Link()))
+	session.MakeRequest(t, req, http.StatusNotFound)
+	req = NewRequest(t, "GET", fmt.Sprintf("%s/activity/recent-commits", repo.Link()))
+	session.MakeRequest(t, req, http.StatusNotFound)
+}
+
+func TestRepoActivityOnlyCodeUnitWithEmptyRepo(t *testing.T) {
+	defer tests.PrepareTestEnv(t)()
+	user := unittest.AssertExistsAndLoadBean(t, &user_model.User{Name: "user1"})
+	session := loginUser(t, user.Name)
+
+	unit_model.LoadUnitConfig()
+
+	// Create a empty repo, with only code unit enabled.
+	repo, err := repo_service.CreateRepository(db.DefaultContext, user, user, repo_service.CreateRepoOptions{
+		Name:     "empty-repo",
+		AutoInit: false,
+	})
+	assert.NoError(t, err)
+	assert.NotEmpty(t, repo)
+
+	enabledUnits := make([]repo_model.RepoUnit, 1)
+	enabledUnits[0] = repo_model.RepoUnit{RepoID: repo.ID, Type: unit_model.TypeCode}
+	disabledUnits := []unit_model.Type{unit_model.TypeIssues, unit_model.TypePullRequests, unit_model.TypeReleases}
+	err = repo_service.UpdateRepositoryUnits(db.DefaultContext, repo, enabledUnits, disabledUnits)
+	assert.NoError(t, err)
+
+	req := NewRequest(t, "GET", fmt.Sprintf("%s/activity", repo.Link()))
+	session.MakeRequest(t, req, http.StatusOK)
+
+	// Git repo empty so no activity for contributors etc
+	req = NewRequest(t, "GET", fmt.Sprintf("%s/activity/contributors", repo.Link()))
+	session.MakeRequest(t, req, http.StatusNotFound)
+	req = NewRequest(t, "GET", fmt.Sprintf("%s/activity/code-frequency", repo.Link()))
+	session.MakeRequest(t, req, http.StatusNotFound)
+	req = NewRequest(t, "GET", fmt.Sprintf("%s/activity/recent-commits", repo.Link()))
+	session.MakeRequest(t, req, http.StatusNotFound)
+}
+
+func TestRepoActivityOnlyCodeUnitWithNonEmptyRepo(t *testing.T) {
+	defer tests.PrepareTestEnv(t)()
+	user := unittest.AssertExistsAndLoadBean(t, &user_model.User{Name: "user1"})
+	session := loginUser(t, user.Name)
+
+	unit_model.LoadUnitConfig()
+
+	// Create a repo, with only code unit enabled.
+	repo, _, f := CreateDeclarativeRepo(t, user, "", []unit_model.Type{unit_model.TypeCode}, nil, nil)
+	defer f()
+
+	req := NewRequest(t, "GET", fmt.Sprintf("%s/activity", repo.Link()))
+	session.MakeRequest(t, req, http.StatusOK)
+
+	// Git repo not empty so activity for contributors etc
+	req = NewRequest(t, "GET", fmt.Sprintf("%s/activity/contributors", repo.Link()))
+	session.MakeRequest(t, req, http.StatusOK)
+	req = NewRequest(t, "GET", fmt.Sprintf("%s/activity/code-frequency", repo.Link()))
+	session.MakeRequest(t, req, http.StatusOK)
+	req = NewRequest(t, "GET", fmt.Sprintf("%s/activity/recent-commits", repo.Link()))
+	session.MakeRequest(t, req, http.StatusOK)
+}
+
+func TestRepoActivityOnlyIssuesUnit(t *testing.T) {
+	defer tests.PrepareTestEnv(t)()
+	user := unittest.AssertExistsAndLoadBean(t, &user_model.User{Name: "user1"})
+	session := loginUser(t, user.Name)
+
+	unit_model.LoadUnitConfig()
+
+	// Create a empty repo, with only code unit enabled.
+	repo, err := repo_service.CreateRepository(db.DefaultContext, user, user, repo_service.CreateRepoOptions{
+		Name:     "empty-repo",
+		AutoInit: false,
+	})
+	assert.NoError(t, err)
+	assert.NotEmpty(t, repo)
+
+	enabledUnits := make([]repo_model.RepoUnit, 1)
+	enabledUnits[0] = repo_model.RepoUnit{RepoID: repo.ID, Type: unit_model.TypeIssues}
+	disabledUnits := []unit_model.Type{unit_model.TypeCode, unit_model.TypePullRequests, unit_model.TypeReleases}
+	err = repo_service.UpdateRepositoryUnits(db.DefaultContext, repo, enabledUnits, disabledUnits)
+	assert.NoError(t, err)
+
+	req := NewRequest(t, "GET", fmt.Sprintf("%s/activity", repo.Link()))
+	session.MakeRequest(t, req, http.StatusOK)
+
+	// Git repo empty so no activity for contributors etc
+	req = NewRequest(t, "GET", fmt.Sprintf("%s/activity/contributors", repo.Link()))
+	session.MakeRequest(t, req, http.StatusNotFound)
+	req = NewRequest(t, "GET", fmt.Sprintf("%s/activity/code-frequency", repo.Link()))
+	session.MakeRequest(t, req, http.StatusNotFound)
+	req = NewRequest(t, "GET", fmt.Sprintf("%s/activity/recent-commits", repo.Link()))
+	session.MakeRequest(t, req, http.StatusNotFound)
+}